Я столкнулся с этим «прекрасным» примером «хорошо читаемого» и «элегантного» кода, но у меня возникли проблемы с его пониманием:
struct S {
[[noreturn]] virtual inline auto f(const unsigned long int *const)
–> void const noexcept;
};
Вот что я понимаю (пожалуйста, поправьте меня, если я ошибаюсь):
f()
является функцией-членом S
virtual
— может быть переопределено производными классамиinline
— компилятор должен попытаться генерировать код для звонка в f
вместо того, чтобы называть это нормальноconst
— функция не может изменить любой из S
участникиnoexcept
— функция никогда не сгенерирует (не может сгенерировать или не сгенерировать)const
указатель на const unsigned long int
auto .... -> void
— суффикс возвращаемого типа void
[[noreturn]]
— это никогда return
sВот мои основные проблемы:
[[noreturn]]
, Это никогда возвращается к своему абоненту; так как он может иметь тип возвращаемого значения void
? Каков смысл возвращаемого типа в этой функции?int
вместо void
например? }
)?Я не смог заставить этот код работать в VS2013 Preview, поэтому я полагаю, что эти функции еще не реализованы.
Мне очень любопытно, поэтому я буду признателен, если кто-нибудь сможет объяснить! ура
[[noreturn]]
это атрибут, который имеет любую семантику. Однако не меняется способ объявления функции: все нормальные функции в C ++ (то есть все функции, кроме конструкторов, деструкторов и операторов преобразования) имеют объявленный тип возврата. Добавление любого атрибута не меняет это правило.
Цель [[noreturn]]
Атрибут, вероятно, указывает на то, что функция никогда не возвращается нормальным способом. Учитывая, что функция также объявлена noexcept
это в основном означает, что соответствующая функция также не может вызвать исключение. Одним из примеров функции с похожим поведением является exit()
который завершает программу. Я мог предположить, что функции, реализующие некоторый цикл приложения, также могли бы быть квалифицированы. В любом случае, [[noreturn]]
сообщает системе, что соответствующая функция никогда не вернется, т. е. падение функции («после»), вероятно, приведет к неопределенному поведению.
Если функция объявлена как [[noreturn]], она никогда не возвращается к своему вызывающему; так как он может иметь возвращаемый тип void? Каков смысл возвращаемого типа в этой функции?
От этот Q&A вы можете видеть, что noreturn — это способ сообщить компилятору, что функция не возвращает. Обычно это означает, что он либо имеет бесконечный цикл (часто встречающийся на серверах, которые должны работать бесконечно), либо вызывает exit()
, terminate()
и тому подобное, выход из приложения без возврата к основному.
[[noreturn]]
не является обязательным, то есть вы не иметь указать это. Это атрибут, то есть основной синтаксис определения / объявления функции остается неизменным, поэтому функция имеет иметь тип возвращаемого значения, как и любая другая функция.
Будет ли этот код компилироваться с int вместо void, например?
Да, это так, хотя компилятор может предупредить вас, что не имеет смысла возвращать что-то из функции, которая никогда не вернется.
Что будет практического использования для такой функции? Бросить исключение?
Первое, что приходит на ум, — это какой-то бесконечный цикл, например, обработка входящих запросов на сервере. Бросать исключение можно [[noreturn]]
функции, но это не совсем вариант, потому что он явно говорит noexcept
, Бросок вызовет вызов std::terminate()
, что приводит к самому завершению программы, но прежде к определенному для реализации количеству разматывания стека, что фактически означает [[noreturn]]
все равно будет применимо.
Куда идет поток кода после завершения выполнения этой функции (после})?
Функция никогда не достигает своего закрытия }
, Он либо работает бесконечно (до тех пор, пока кто-то не потянет за штекер), либо он выходит из строя ненормально, то есть по завершению программы. Другими словами, если функция больше не выполняется, она на самом деле не завершена, но прервана выполнение, и нет программы и потока управления для перехода.
Другие ответы великолепны, но я собираюсь представить альтернативный ответ для
Если функция объявлена как
[[noreturn]]
никогда не возвращается к своему вызывающему; так как он может иметь возвращаемый тип void? Каков смысл возвращаемого типа в этой функции?
Одна из причин, по которой вам может понадобиться тип возвращаемого значения (и, в этом случае, возвращаемый тип, отличный от void), заключается в том, что функция переопределяет метод суперклассов.
struct Parent {
virtual int f()=0;
}
struct Child {
[[noreturn]] override int f() noexcept { ... }
};
В некоторых случаях компилятор сможет использовать [[noreturn]]
производить лучший код. Но в других ситуациях f
может быть назван полиморфно, и, следовательно, должен соответствовать подписи своих родителей.