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

Что возвращает sizeof (имя функции)?

пример кода:

main ()
{
printf ("size = %d\n", sizeof (main));
}
4b9b3361

Ответ 1

Стандарт

C запрещает его - при компиляции с gcc -pedantic он выдает предупреждение invalid application of ‘sizeof’ to a function type.

Однако gcc компилирует его и возвращает 1 для sizeof(main), и это не размер указателя функции.

Кажется, что он зависит от компилятора.

Ответ 2

Оператор sizeof

 sizeof unary-expression
 sizeof ( type-name )

Операнд - это либо идентификатор, который является унарным выражением, либо выражением типа (то есть спецификатором типа, заключенным в круглые скобки). Унарное выражение не может представлять объект битового поля, неполный тип или function designator. Результатом является неподписанная интегральная постоянная. Стандартный заголовок STDDEF.H определяет этот тип как size_t.

Использовать флаг компиляции -Wall -pedantic, чтобы выпустить предупреждение о некорректном операнде на sizeof (запомнить sizeof - оператор времени компиляции), Код:

$ cat sizeof.c 
#include<stdio.h> 
int main(){
    printf("%zu %p\n", sizeof(main), (void*)main);
    return 0;
} 

Сообщение компиляции с GCC версии 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5):

$ gcc -Wall -pedantic sizeof.c -std=c99
sizeof.c: In function ‘main’:
sizeof.c:3:30: warning: invalid application of ‘sizeof’ to a function type 
              [-pedantic]
sizeof.c:3:38: warning: ISO C forbids conversion of function pointer to 
              object pointer type [-pedantic]

Читайте также:

6.5.3.4 Оператор sizeof

1118 — Оператор sizeof не должен применяться к выражению, имеющему тип функции или неполный тип, к имени в скобках такого типа или выражению, которое обозначает член битового поля 1127 — Значение результата определяется реализацией, а его тип (целочисленный тип без знака) size_t, определенный в <stddef.h> (и других заголовках)

Кроме того, правильная строка формата для size_t равна %zu, и если она не существует, например, компилятор Microsoft, вы можете использовать %lu и преобразовать возвращаемое значение в unsigned long.

Ответ 3

ISO С++ запрещает применение sizeof к выражению типа функции.

ISO/IEC 14882 на С++ говорит (раздел 5.3.3):

"Оператор размера не должен применяться к выражению, которое имеет функцию или неполный тип,..."

То же самое относится к стандарту C (ISO/IEC 9899: 1999), раздел 6.5.3.4:

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

Ответ 4

В соответствии с разделом ISO C11 6.5.3.4 The sizeof and _Alignof operators, подраздел 1 (ограничения):

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

В разделе 6.3.2.1 Lvalues, arrays, and function designators также есть подраздел 4, в котором говорится:

Обозначение функции - это выражение, имеющее тип функции. За исключением случаев, когда это операнд оператора sizeof, оператор _Alignof (65) или унарный оператор &, обозначение функции с возвращаемой функцией типа type "преобразуется в выражение, которое имеет тип" указатель на функцию возврата типа "".

Нота ноты 65, на которую ссылается, уточняет точку:

Поскольку это преобразование не происходит, операнд оператора sizeof или _Alignof остается обозначением функции и нарушает ограничения в 6.5.3.4.

В соответствии с разделом 4 Conformance:

В настоящем Международном стандарте термин "должен" должен интерпретироваться как требование о реализации или о программе; наоборот, "не должно" интерпретироваться как запрет .

Следовательно, строго соответствующая программа никогда не должна брать размер функции. Но, опять же, вероятно, он должен также использовать правильную форму main(): -)

Однако здесь есть лазейка. Соответствующей реализации разрешено предоставлять расширения "при условии, что они не изменяют поведение каких-либо строго соответствующая программа "(раздел 4 Conformance, подраздел 6).

Вы можете утверждать, что это поведенческое изменение (разрешая sizeof(function), а не запрещая его), но поскольку исходная программа не была бы строго соответствовать, в первую очередь, подраздел не запрещает ее.