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

431
08 мая 2017, 02:42

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

Answer 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<void>(f()); // нет предупреждения о не использованном результате

[[noreturn]]

Говорит о том, что функция не возвращает управление. Может быть применим к объявлению функции. Актуально для функций, которые заканчивают свою работу выкидыванием исключения, выполняют вечный цикл или прерывают выполнение всей программы. Пример:

[[noreturn]] 
void f() {
    throw "error";
}

Если функция, помеченная атрибутом [[noreturn]], возвращает управление на одной из веток выполнения, то это приводит к неопределённому поведению.

READ ALSO
QTableView отображение изображения

QTableView отображение изображения

Допустим есть класс BookВ нем хранится описание книги и QImage

436
Написать список вещественных чисел с++ [требует правки]

Написать список вещественных чисел с++ [требует правки]

Помогите , срочноМне надо написать список вещественных чисел, и после серии подряд идущих повторяющихся чисел вставить количество их повторений

250