C++ Logo

liaison

Advanced search

Re: [isocpp-wg14/wg21-liaison] qualifier and type deduction

From: Jens Maurer <jens.maurer_at_[hidden]>
Date: Tue, 28 Apr 2026 23:54:51 +0200
On 4/28/26 19:25, Martin Uecker wrote:
> Am Dienstag, dem 28.04.2026 um 18:43 +0200 schrieb Jens Maurer:
>>
>> On 4/28/26 15:56, Martin Uecker wrote:
>>>> In Aaron's and my alternate world, we'd need a more nuanced brush for
>>>> "dropping qualifiers" when forming the signature of a function in C.
>>>>
>>>> void f(int * const); === void f(int *);
>>>>
>>>> But maybe don't drop the _Optional here when forming the signature:
>>>>
>>>> void f(int * _Optional);
>>>
>>> But "not dropping the qualifier" would follow naturally when putting
>>> it on the pointee. So this would seem to give you the right semantics
>>> using existing language mechanisms when putting on the pointee. So now
>>> I am even more confused about what the problem is.
>>
>> I guess part of the problem is how much of _Optional is part of the
>> type system.
>
> Whether one wants a type-system solution or not can certainly
> be discussed.
>
> But I actually didn't want to discuss the overall design, but
> understand the C++-specific issue which the papers tries to point out.
> I am still completely at loss regarding this point.
>
> To me it seems that _Optional, as designed, would also do exactly
> the right thing for templates.

Let's try again, and with a more basic template,
in a hypothetical world where C's _Optional feature is
transplanted into C++.

template<class T>
int f(T *ptr);

_Optional int *p;
int x = f(p);

What is the type of "T" here? Assuming _Optional works like "const",
T = _Optional int.

Now, suppose f is defined as follows:

template<class T>
int f(T *ptr)
{
  T x = 0;
  int y;
  return 0;
}

Is the definition of the local variable "x" valid? Its type is
"_Optional int", and I believe the _Optional paper says that's
ill-formed. It feels novel that a qualifier on a type can
radically change the answer to the question "can I have an
object of that type". (I suppose C can get to a similar place
with its typeof operator.)

So, the possibly pre-existing template "f" above, when now used
with an _Optional int*, is ill-formed in its definition,
which used to work fine for T=int or T="const int".

Can we put an overload of f triggering on the presence of
_Optional next to the above "f"? Not really.

template<class T>
int f(_Optional T *ptr);

doesn't work; the "T" must be the only type-specifier.

>>> and for "_Optional"
>>> it says that an access without prior null pointer check
>>> is forbidden.
>>
>> And that seems qualitatively different to me: We (want to)
>> diagnose the formation of *x (the lvalue) without a surrounding
>> "if" guard, not the use of that lvalue afterwards.
>>
>> So, it's a restriction on stuff you can do with the pointer x,
>> not on stuff you can do with the lvalue formed by *x.
>
> We would want to diagnose the unprotected access and not
> already the formation of *x. So in both cases we
> restrict how the lvalue *x can be accessed while the pointer
> value itself can be passed around without any restriction.

At least in C++, writing *x (where x is a null pointer)
is undefined behavior, because it (colloquially) creates
a "null lvalue", which is undefined behavior. Without any
access via *x itself. So, it's not about "how the lvalue
can be used"; there might not be an lvalue to start with.

Jens

Received on 2026-04-28 21:54:54