Почему gcc предупреждает о decltype (main()), но не clang?
Возьмите следующий код:
int main()
{
decltype(main()) x = 0;
return x;
}
gcc жалуется:
main.cpp: In function 'int main()':
main.cpp:8:19: warning: ISO C++ forbids taking address of function '::main' [-Wpedantic]
decltype(main()) x = 0;
^
main.cpp:8:19: warning: ISO C++ forbids taking address of function '::main' [-Wpedantic]
но не clang. Так что насчет decltype(main())
вызывает эту ошибку? Как decltype
берет адрес основного?
Ответы
Ответ 1
Диагностика GCC может быть неправильно сформулирована в этом случае, потому что decltype
не нужно знать адрес main
; он должен знать только его тип. Однако предупреждение основано на следующем стандарте (§3.6.1/3):
Функция main
не должна использоваться в программе.
Я предполагаю, что GCC интерпретирует это как означающее, что вы даже не можете использовать его в неоцениваемом выражении.
Clang (версия 3.4 в любом случае), похоже, вообще не реализует это правило, даже если я включу все флаги, о которых я могу думать, и даже если main
вызывает себя рекурсивно. Вот почему это не дает вам предупреждения.
Ответ 2
Этот вопрос на самом деле появился недавно в undefined группе обсуждения по исследованию поведения по умолчанию в потоке Что означает "функция main не должна использоваться внутри программы" означает?. Это не сразу, но здесь начинается там, где указан следующий оператор:
Я не думаю, что decltype (main()) является odr-use, или SizeOf (decltype (основной)).
очень сокращенный набор ответов выглядит следующим образом:
Правда, я просто не понимаю, какая это будет. Вы могли бы означать sizeof (decltype (& main)) в последнем случае.
Я думаю, что наиболее распространенное использование ODR без использования ODR будет определять его после передовая декларация, и теперь Стивен Кламаж пояснил, что должны быть плохо сформированы. Более широкое определение "использования" как результат поиска имени без ссылки на ODR выглядит корректно.
и
У С++ 98 упоминание "use" имело перекрестную ссылку на 3.2 [basic.def.odr]. С++ 11 больше не имеет перекрестной ссылки и не был изменен, чтобы сказать "odr-use", поэтому я ожидаю, что это означает любое использование.
и, как представляется, интерпретация раздела 3.6.1
Основная функция, которая гласит:
Функция main не должна использоваться внутри программы. [...]
означает любое использование даже в необоснованных контекстах и поэтому gcc
здесь является правильным, чтобы создать ошибку, хотя само сообщение не имеет смысла.
Обновить
Интересно и поучительно отметить, что оригинальное предложение : N3154, чтобы исправить Отчет о дефектах 1109 изменил бы 3.6.1
на:
Функция main не должна использоваться в качестве параметра (3.2) в программе....
который допустил бы пример decltype
, но был изменен, если принят, и мы видим, что новый предложение: N3214 изменилось на то, что у нас есть сегодня:
Функция main не должна использоваться в программе
который будет строго указывать на мнение в списке рассылки UB, что любое использование main
плохо сформировано, действительно верно.