Подтвердить что ты не робот

Является ли sizeof (void()) законным выражением?

Из [5.3.3/1] я обнаружил, что:

Оператор sizeof не применяется к выражению, которое имеет функцию или неполный тип

Из [3.9/5] Я обнаружил, что:

Неполно определенные типы объектов и cv void являются неполными типами

В любом случае, для sizeof не оценивает его операнды, я бы сказал, что sizeof(void()) является юридическим выражением (на самом деле GCC компилирует его, а результат равен 1). С другой стороны, из здесь, void не упоминается при обсуждении sizeof, ни когда упомянуты типы с размером 1, ни в списке которые имеют определенный размер реализации.

Возникает вопрос: есть ли sizeof(void()) юридическое выражение?
Гарантируется ли размер равным 1?
Или это юридическое выражение, приводящее к UB и что все?

4b9b3361

Ответ 1

void() - это тип функции (это функция, которая не принимает аргументов и ничего не возвращает), поэтому она не является допустимым типом в sizeof().

Ответ 2

От взгляда на CppReference.com - оператор sizeof документация буквально гласит:

sizeof не может использоваться с типами функций, неполными типами или бит-поля.

А так как void() - это тип функции, то sizeof(void()) не является юридическим выражением.

В своем примере использования мы можем увидеть комментарий ошибки в этой строке:

std::cout << "size of function: " << sizeof(void()) << '\n'; // error

Ответ 3

Кроме того, если вы скомпилируете код, например, пример ниже:

#include <iostream>

int main()
{
   std::cout << sizeof(void());
}

Код компилируется правильно и создает значение 1, но если вы посмотрите на компиляцию, вы увидите следующее:

main.cpp: В функции 'int main()':

main.cpp: 5: 29: предупреждение: недопустимое применение 'sizeof' к типу функции [-Wpointer-arith]

std:: cout < SizeOf (недействительный());

Итак, очевидно, что sizeof() не применяется для типов функций, поэтому код создает предупреждение. Это неверно.


Код здесь

Ответ 4

Небольшая предпосылка.

Вопрос возник из-за неправильного толкования оператора 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 компилирует код с предупреждением.

Ответ 5

Как уже выделено в документах здесь 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).

Ответ 6

Straigth из ссылки C99 NO

Указанный в документе раздел 6.5.3.4 Оператор sizeof:

Оператор sizeof не должен применяться к выражению, имеющему тип функции или неполный тип, к имени в скобках такого типа или к выражению, которое обозначает член битового поля.

В соответствии с пунктами 19 и 20 раздела 6.2.5 Типы:

  1. Тип void содержит пустой набор значений; это неполный тип, который не может быть завершен.
  2. ... Тип функции описывает функцию с указанным типом возвращаемого значения. Тип функции характеризуется возвращаемым типом, числом и типами его параметров. Тип функции называется производным от его возвращаемого типа, и если его возвращаемым типом является T, тип функции иногда называют "функцией", возвращающей T. Конструкция типа функции из типа возврата называется "производным типом функции".

Таким образом, void() - это тип функции, полученный из неполного типа, и его незаконный как операнд для sizeof. Тем не менее, его доходность будет зависеть от реализации компилятора и не имеет гарантированного возврата.

C99 Standard