Thank you for the summary, I agree with your take on consensus so far.
I prefer using the attribute-based proposal and not inferring based on the name of standard library identifiers (I generally dislike the compiler getting clever about knowing “special” C++ APIs because of how incredibly difficult lookup is in C++ – things like using declarations, inline anonymous namespaces, template specializations, etc make it more effort than for C APIs.) That said, I can live with a name-based lookup if that’s got stronger consensus.
I do have design questions though. Instead of making [[clang::nullable]]
, should we reuse _Nullable
(et al)? Then the rule is “pointers are _Nullable as are any class type marked _Nullable” which seems pretty easy for users to understand and for us to implement.
Also, here are some code snippets with questions…
struct __Nullable Base {
};
struct Derived : Base { // Is this nullable?
};
struct PrivatelyDerived : private Base { // Is this nullable?
};
template <typename Ty>
void func(Ty Foo);
template <>
void func<Base>(_Nullable Base Foo); // Is this okay? (I assume so)
template <typename Ty>
void other_func(_Nullable Ty Foo);
void call_it() {
other_func(Base{}); // Is this okay? (I assume so)
other_func(0); // Is this okay? (I assume it's an instantiation error because int is not nullable)
}
struct NotNullable {};
using Errr _Nonnull = NotNullable; // Is this allowed and is Errr nullable?
using Uhhhh = NotNullable _Nonnull; // Is this allowed and is Uhhhh nullable?
// I assume typedef will work the same way as using aliases.