Стандарт C++ явно не запрещает большинство плохо сформированных конструкций, включая этот. Этого достаточно, чтобы не было явно или неявно разрешено быть плохо сформированным.
Соответствующая реализация на С ++ позволяет принимать что-либо вообще, включая плохо сформированные программы на С ++. Однако требуется, по крайней мере, одна диагностика, если вход не является хорошо сформированной программой на С ++ (за исключением случаев, когда в стандарте присутствует явное предложение «нет необходимости диагностики»). Таким образом, вопрос о том, какой подходящий компилятор разрешен делать, зависит от вопроса о том, является ли рассматриваемая программа хорошо сформированной.
Для решения этого последнего вопроса мы должны установить, имеет ли значение constexpr
. Ответ на это - это «нет». Ключевое слово constexpr
вызывает определенные выражения, которые в противном случае не являются константными выражениями, чтобы стать таковыми и не имеют другого смысла. В свою очередь, константные выражения отличаются от простых выражений ванили в строго ограниченном числе четко определенных контекстов, таких как объявления массивов или экземпляры шаблонов. В таких контекстах непостоянное выражение сделает программу плохо сформированной. Поскольку такой контекст не присутствует в рассматриваемой программе, мы должны заключить, что constexpr
не имеет никакого отношения к правильности программы.
В частности, постоянное выражение не освобождает выражение от его обязательства быть правильным по типу. В качестве простейшего примера,
`(int*)nullptr - (int*)nullptr`
хорошо сформированы, в то время как
`(int*)nullptr - (double*)nullptr`
является типом-неверны и, таким образом, плохо сформированы, несмотря на оба операнда быть постоянные выражения, известные во время компиляции, чтобы быть равным до nullptr
.
Отказ от ответственности: C-стиль применяется только для демонстрационных целей, поскольку они лучше читаются в коротких фрагментах кода. Не используйте их в производственном коде.
Итак, мы должны проверить, хорошо ли сформирована программа constexpr
или нет.Этот вопрос, на удивление, не имеет прямого ответа в стандарте и вообще не может дать никакого ответа. Согласно статически типизированной природе C++, вызов должен быть плохо сформирован, но я не мог найти прямого утверждения об этом. Вместо того, чтобы размышлять о потенциальных последствиях этого, я бы предпочел объявить это техническим дефектом стандарта и назвать его днем.
Стандарт делает косвенно утверждать, что аргументы функции по умолчанию являются свойством функции декларации, а не сами функций:
(8.3.6/4) Объявлений в разных областях имеют совершенно разные наборы аргументов по умолчанию
Таким образом, указатель функции, являющийся сущностью, которая ссылается на функцию, а не на объявление функции, не должен иметь примененных аргументов по умолчанию.
Этот вопрос является дистилляцией моего предыдущего [связанного вопроса] (http://stackoverflow.com/questions/35966588) (плохой, в ретроспективе). –
В «все равно будет соответствовать», вы имеете в виду: будет ли компилятор соответствовать? –
Я не вижу там, где говорится, что аргументы по умолчанию не должны применяться даже для случая, отличного от constexpr –