I'm accustomed to using __attribute__((nonnull))
when expressing pointers that should not be null.
void f(int* ptr) __attribute__((nonnull));
int main(){
int* ptr = new int(1);
f(ptr);
}
void f(int* ptr){/*impl*/}
However, with the GSL, there is also the not_null<T*>
wrapper type.
void function1(gsl::not_null<int*> n);
void f(gsl::not_null<int*> n);
int main(){
int* ptr = new int(1);
f(ptr);
}
void f(gsl::not_null<int*> n){/*impl*/}
Assuming the language facilities are there to support the GSL version, should I always be using not_null<T*>
in place of __attribute__((nonnull))
now?
I've been under the impression that the compiler attribute may aid in optimizations, but the wrapper version resolves down to an unattributed pointer.
"should I always be using not_null in place of attribute((nonnull)) now?
not_null
seems the better approach and here is why:
__attribute__((nonnull))
seems to be gcc specific so this means that only gcc could use this attribute for optimizations, safety, security, static code analyzers (etc, you name it). This makes it not a very good choice if you want to use multiple compilers. Microsoft has for example __assume
which can be used to achieve a similar results.
gsl::not_null
is not part of the Standard Template Library so there is no guarantee that it will work on all compilers the same way. You might find that on some compilers it will do absolutely nothing special. However this is a better choice because not_null
could wrap all compiler variations to achieve the same result (also runtime checking can be added). But judging from the current implementation (see link) there is only support for Microsoft compiler using __assume
(could not find implementations for gcc, but if you have one then it's an advantage to use it)