2016-07-28 2 views
5

Я привык использовать __attribute__((nonnull)) при выражении указателей, которые не должны быть пустыми.Когда я использую «__attribute __ ((nonnull))« vs »not_null <T*>«?

void f(int* ptr __attribute__((nonnull))); 

int main(){ 
    int* ptr = new int(1); 
    f(ptr); 
} 
void f(int* ptr){/*impl*/} 

Однако, с GSL, есть также тип not_null<T*> обертки.
void function1 (gsl :: not_null 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*/} 

Предполагая, что языковые объекты там, чтобы поддержать версию GSL, я должен всегда использовать not_null<T*> вместо __attribute__((nonnull)) сейчас?

У меня создалось впечатление, что атрибут компилятора может помочь в оптимизации, но версия-оболочка разрешается до непринятого указателя.

+2

Один вопрос: '' __attribute __ ((nonnull)) «переносится через основные компиляторы? – WhiZTiM

+0

Почему бы не использовать ссылку или 'span'? – Jarod42

ответ

2

«я должен всегда использовать NOT_NULL вместо атрибут ((ненулевая)) Теперь

not_null кажется лучший подход, и вот почему:

__attribute__((nonnull)), кажется, gcc, поэтому это означает, что только gcc может использовать этот атрибут для оптимизации, безопасности, безопасности, анализаторов статического кода (и т. д., вы его называете). Это делает его не очень хорошим выбором, если вы хотите использовать несколько компиляторов. __assume, которые могут быть использованы для достижения аналогичных результатов.

gsl::not_null не входит в стандартную библиотеку шаблонов, поэтому нет гарантии, что он будет работать на всех компиляторах одинаково. Вы можете обнаружить, что на некоторых компиляторах ничего особенного не будет. Однако это лучший выбор, потому что not_null может обернуть все варианты компилятора для достижения того же результата (также можно добавить проверку времени выполнения). Но, судя по текущей реализации (см. Ссылку), поддерживается только компилятор Microsoft, используя __assume (не удалось найти реализации для gcc, но если у вас есть одно, то это преимущество для его использования)

+0

gsl :: not_null использует функциональность GCC и Clang, аналогичную функции __assume от MSVC. OTOH, то есть * не * идентичен результату, полученному атрибутом nonnull, первый - это лишь намек, последний является гарантией. –