Ответ 1
void()
- это тип функции (это функция, которая не принимает аргументов и ничего не возвращает), поэтому она не является допустимым типом в sizeof()
.
Из [5.3.3/1] я обнаружил, что:
Оператор sizeof не применяется к выражению, которое имеет функцию или неполный тип
Из [3.9/5] Я обнаружил, что:
Неполно определенные типы объектов и cv void являются неполными типами
В любом случае, для sizeof
не оценивает его операнды, я бы сказал, что sizeof(void())
является юридическим выражением (на самом деле GCC компилирует его, а результат равен 1).
С другой стороны, из здесь, void
не упоминается при обсуждении sizeof
, ни когда упомянуты типы с размером 1, ни в списке которые имеют определенный размер реализации.
Возникает вопрос: есть ли sizeof(void())
юридическое выражение?
Гарантируется ли размер равным 1?
Или это юридическое выражение, приводящее к UB и что все?
void()
- это тип функции (это функция, которая не принимает аргументов и ничего не возвращает), поэтому она не является допустимым типом в sizeof()
.
От взгляда на CppReference.com - оператор sizeof документация буквально гласит:
sizeof
не может использоваться с типами функций, неполными типами или бит-поля.
А так как void()
- это тип функции, то sizeof(void())
не является юридическим выражением.
В своем примере использования мы можем увидеть комментарий ошибки в этой строке:
std::cout << "size of function: " << sizeof(void()) << '\n'; // error
Кроме того, если вы скомпилируете код, например, пример ниже:
#include <iostream>
int main()
{
std::cout << sizeof(void());
}
Код компилируется правильно и создает значение 1, но если вы посмотрите на компиляцию, вы увидите следующее:
main.cpp: В функции 'int main()':
main.cpp: 5: 29: предупреждение: недопустимое применение 'sizeof' к типу функции [-Wpointer-arith]
std:: cout < SizeOf (недействительный());
Итак, очевидно, что sizeof()
не применяется для типов функций, поэтому код создает предупреждение. Это неверно.
Небольшая предпосылка.
Вопрос возник из-за неправильного толкования оператора sizeof
.
Фактически ОП считал void()
выражение, которое имеет неполный тип в контексте sizeof
, и сам вопрос может быть прочитан как - почему sizeof
принимает выражение void()
, которое является неполным типом и не должно быть принято как указано в рабочем проекте?
Вот почему [3.9/5] упоминается фактически, иначе это не имело бы смысла.
Тем не менее, факт состоит в том, что вопрос содержит фактически два интересных вопроса:
Почему sizeof(void())
не является законным?
Это фактический вопрос, как из самого названия.
Почему sizeof((void()))
не является законным?
Это предполагаемый вопрос OP.
Ответы ниже:
void()
в sizeof(void())
интерпретируется как тип функции, и он плохо сформирован, как для [5.3.3/1] (акцент мой):
Оператор sizeof не должен применяться к выражению с функцией или неполным типом, к указанному в скобках имени таких типов, [...]
(void())
in sizeof((void()))
- это выражение с неполным типом void
(обратите внимание, что sizeof
- неоценимый контекст), и он плохо сформирован как [5.3.3/1] (выделено мной):
Оператор sizeof не должен применяться к выражению, которое имеет функцию или неполный тип, к имени в скобках таких типов, [...]
В обоих случаях GCC компилирует код с предупреждением.
Как уже выделено в документах здесь http://en.cppreference.com/w/cpp/language/sizeof
Примечания
sizeof()
нельзя использовать с типами функций, неполными типами или gl-значениями бит-поля.
Так как void()
- это тип функции, поэтому его недействительный тип sizeof()
Примечание:
void()
- это функция, которая не принимает аргументов и ничего не возвращает
Цитирование примера из документов:
//<< "size of function: " << sizeof(void()) << '\n' // error
Итак, ответы на ваши вопросы:
1) Нет, это не законное выражение.
2) Он будет отображаться как 1, но покажет предупреждение
3) то же, что и 1).
Straigth из ссылки C99 NO
Указанный в документе раздел 6.5.3.4 Оператор sizeof:
Оператор sizeof не должен применяться к выражению, имеющему тип функции или неполный тип, к имени в скобках такого типа или к выражению, которое обозначает член битового поля.
В соответствии с пунктами 19 и 20 раздела 6.2.5 Типы:
- Тип void содержит пустой набор значений; это неполный тип, который не может быть завершен.
- ... Тип функции описывает функцию с указанным типом возвращаемого значения. Тип функции характеризуется возвращаемым типом, числом и типами его параметров. Тип функции называется производным от его возвращаемого типа, и если его возвращаемым типом является T, тип функции иногда называют "функцией", возвращающей T. Конструкция типа функции из типа возврата называется "производным типом функции".
Таким образом, void() - это тип функции, полученный из неполного типа, и его незаконный как операнд для sizeof. Тем не менее, его доходность будет зависеть от реализации компилятора и не имеет гарантированного возврата.