Что означает этот синтаксис C ++ 11?
[[ noreturn ]] void f () {
throw "error";
}
Рабочий стандарт C ++ N3797 гласит:
В первом объявлении функции должен быть указан возврат
атрибут, если любое объявление этой функции определяет возврат
приписывать. Если функция объявлена сnoreturn
приписывать
одна единица перевода и та же функция объявляется без
атрибут noreturn в другом модуле перевода, программа
плохо сформирован; Диагностика не требуется.
Что подразумевается под атрибутом функции?
Функция определяется своим именем, типом возвращаемого значения и списком формальных параметров, а также их типами. Эти элементы составляют «интерфейс» функции: они важны для вызывающей функции, потому что они определяют способ ее вызова.
Атрибуты, с другой стороны, предоставляют способ сообщить компилятору дополнительные сведения о функции, которые не изменяют его интерфейс. Когда компилятор знает, что функция
fork
), или жекомпилятор может лучше оптимизировать код и предоставлять дополнительные предупреждения / молчать ненужные предупреждения.
Например, если вы пишете
main() {
f();
g();
}
а также f()
отмечен noreturn
компилятор выдаст предупреждение о вызове g()
быть недоступным
Атрибуты являются новой функцией в C ++ 11. Поставщики компиляторов уже давно предлагают специфичные для поставщика расширения, которые позволяют тем или иным образом аннотировать функции, но теперь существует стандартный механизм. Там не так много фактических атрибутов, указанных в стандарте (только noreturn
а также carries_dependency
), но механизм для аннотирования функций сейчас стандартизирован как минимум.
Тем не менее, noreturn
Атрибут имеет нетривиальную семантику: если функция, объявленная с этим атрибутом, действительно возвращает, программа имеет неопределенное поведение. Компиляторы должны (но не обязаны) производить диагностику, если они могут сказать, что вы возвращаетесь из функции возврата. Атрибут полезен для оптимизации и улучшения диагностики.
[[noreturn]]
Атрибут для предупреждения молчания.
#include <stdexcept>
[[noreturn]] void report_error()
{
throw std::runtime_error("error");
}
int f(int x)
{
if (x > 0) {
return x;
}
report_error();
}
int main()
{
f(1);
}
Если нет пользы [[noreturn]]
предупреждение о выходе компилятора в f()
: warning: control may reach end of non-void function
,
Из документации GCC
«Ключевое слово noreturn говорит компилятору о том, что функция не может возвращаться. Затем она может оптимизировать, не обращая внимания на то, что произойдет, если фатальный код когда-либо вернется. Это делает код немного лучше. Что еще более важно, это помогает избежать ложных предупреждений о неинициализированных переменных».