Страницы

Поиск по вопросам

понедельник, 25 ноября 2019 г.

Что такое атрибуты в C++?


Начиная со стандарта c++11 в языке появились так называемые "атрибуты", что это такое и зачем они нужны?
    


Ответы

Ответ 1



Атрибуты позволяют задавать дополнительную информацию для различных конструкций языка таких как типы, переменные, имена, блоки и единицы трансляции. Данная информация в частност может быть использована компилятором для генерации более эффективного кода и предоставления (или наоборот, подавления) предупреждающих сообщений пользователю на уровне конкретных участков кода, а не целой программы или компилируемого файла, как это обеспечивается ключами компиляции. Атрибуты появились в c++11 и к текущему стандарту c++17 были несколько расширены. На данный момент существуют следующие стандартные атрибуты: carries_dependency deprecated fallthrough maybe_unused nodiscard noreturn Набор атрибутов может быть расширен каждой конкретной реализацией компилятора, таком случае его поведение будет описываться отдельно. Неизвестный атрибут будет проигнорирован, но может быть выведено предупреждающее сообщение. Атрибут всегда обрамляется двойными квадратными скобками: [[атрибут]] Пойдём по порядку: [[carries_dependency]] Данный атрибут не изменяет смысл программы, но может приводить к генерации боле эффективного кода. Атрибут может применяться как к целой функции, так и к её параметрам Может быть полезен на системах со слабо упорядоченной архитектурой при передаче значения между вычислительными потоками. Самый сложный для понимания атрибут :) Поэтому за дополнительной информацией - на enSO. [[deprecated]] Позволяет отметить сущность устаревшей или небезопасной, но тем не менее пока ещ разрешённой к использованию. Может применяться к объявлению класса, typedef-имени, переменной нестатическому члену данных, функции, пространству имён, перечислению, элементу перечисления или специализации шаблона. Атрибут может быть снабжен аргументом, заданным строковым литералом. Например: [[deprecated("используйте функцию g()")]] void f(); Текстовое сообщение будет использовано как подсказка при выводе соответствующег предупреждения. [[fallthrough]] Данный атрибут применяется к пустой операции, т.е. ;. Может быть использован тольк внутри switch для уведомления компилятора о задуманном программистом "проваливании цепочки действий из одной ветки case в другую. Атрибут позволяет подавлять предупреждение компилятора, которое он может выдать, если между метками case не будет обнаружен оператор break. Часто отсутствие break может быть банальной ошибкой, возникшей по невнимательности. Пример: switch (i) { case 1: ... [[fallthrough]]; case 2: ... } [[maybe_unused]] Используется для уведомления компилятора о том, что сущность может быть не использован в программе и следует подавлять соответствующее предупреждение. Может применяться объявлению класса, typedef-имени, переменной, нестатическому члену данных, функции, пространству имён, перечислению или элементу перечисления. Атрибут может быть полезен при наличии отладочного кода, который не будет включён в бинарник при сборке в release режиме. Пример: [[maybe_unused]] void f([[maybe_unused]] bool thing1, [[maybe_unused]] bool thing2) { [[maybe_unused]] bool b = thing1 && thing2; assert(b); } Ранее приходилось использовать приведение к void для подавления возможных предупреждений. [[nodiscard]] Указывает на обязательность использования результата при возврате из функции. Може быть применим как к типу (при объявлении класса или перечисления), так и непосредственно к возвращаемому типу функции. Пример: [[nodiscard]] int f() { return 42; } ... f(); // сообщение о том, что результат функции не использован Явное приведение результата к void подавляет действие атрибута: static_cast(f()); // нет предупреждения о не использованном результате [[noreturn]] Говорит о том, что функция не возвращает управление. Может быть применим к объявлени функции. Актуально для функций, которые заканчивают свою работу выкидыванием исключения, выполняют вечный цикл или прерывают выполнение всей программы. Пример: [[noreturn]] void f() { throw "error"; } Если функция, помеченная атрибутом [[noreturn]], возвращает управление на одной из веток выполнения, то это приводит к неопределённому поведению.

Комментариев нет:

Отправить комментарий