Когда я использую & quot; __ атрибут __ ((ненулевой)) & quot; vs «not_null» T * & gt; «

Я привык к использованию __attribute__((nonnull)) при выражении указателей, которые не должны быть нулевыми.

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)) сейчас?

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

5

Решение

«я должен всегда использовать not_null вместо атрибут((ненулевой)) сейчас?

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

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

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

2

Другие решения

Вы должны использовать их обоих.

gsl :: not_null для времени выполнения.
__attribute __ ((nonnull)) для времени компиляции. Может использоваться как подсказка для статического анализатора.

0

По вопросам рекламы [email protected]