пример кода:
main ()
{
printf ("size = %d\n", sizeof (main));
}
пример кода:
main ()
{
printf ("size = %d\n", sizeof (main));
}
C запрещает его - при компиляции с gcc -pedantic
он выдает предупреждение invalid application of ‘sizeof’ to a function type
.
Однако gcc
компилирует его и возвращает 1
для sizeof(main)
, и это не размер указателя функции.
Кажется, что он зависит от компилятора.
Оператор 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
.
ISO С++ запрещает применение sizeof
к выражению типа функции.
ISO/IEC 14882 на С++ говорит (раздел 5.3.3):
"Оператор размера не должен применяться к выражению, которое имеет функцию или неполный тип,..."
То же самое относится к стандарту C (ISO/IEC 9899: 1999), раздел 6.5.3.4:
"Оператор sizeof не должен применяться к выражению, имеющему тип функции или неполный тип, к имени в скобках такого типа или к выражению, которое обозначает член битового поля."
В соответствии с разделом 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)
, а не запрещая его), но поскольку исходная программа не была бы строго соответствовать, в первую очередь, подраздел не запрещает ее.