Что возвращает sizeof (имя функции)?
Образец кода:
main ()
{
printf ("size = %d\n", sizeof (main));
}
4 ответа
Стандарт C запрещает это - при компиляции с gcc -pedantic
, он производит invalid application of ‘sizeof’ to a function type
предупреждение.
тем не мение gcc
компилирует и возвращает 1
за sizeof(main)
и это не размер указателя функции.
Кажется, это зависит от компилятора.
Размер оператора
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 Размер оператора
1118 -
sizeof
оператор не должен применяться к выражению, имеющему тип функции или неполный тип, к названию в скобках такого типа или к выражению, которое обозначает член битового поля
1127 - Значение результата определяется реализацией, а его тип (целочисленный тип без знака)size_t
, определенный в<stddef.h>
(и другие заголовки)
Кроме того, правильная строка формата для size_t
является %zu
и если он не существует, например, компилятор Microsoft, то вы можете использовать %lu
и преобразовать возвращаемое значение в unsigned long
,
ISO C++ запрещает применение sizeof
к выражению типа функции.
ISO / IEC 14882 на C++ гласит (раздел 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
Оператор не должен применяться к выражению, которое имеет тип функции или неполный тип, к названию в скобках такого типа или к выражению, которое обозначает член битового поля.
Там также подраздел 4 в разделе 6.3.2.1 Lvalues, arrays, and function designators
в котором говорится:
Обозначение функции - это выражение с типом функции. За исключением случаев, когда это операнд
sizeof
оператор,_Alignof
оператор (65) или одинарный&
оператор, обозначение функции с типом "тип, возвращающий функцию" преобразуется в выражение, имеющее тип "указатель на тип, возвращающий функцию".
В примечании 65 к футу, указанном оттуда, поясняется:
Поскольку это преобразование не происходит, операнд
sizeof
или же_Alignof
оператор остается обозначением функции и нарушает ограничения в 6.5.3.4.
Согласно разделу 4 Conformance
:
В этом международном стандарте "должен" должен толковаться как требование к реализации или программе; и наоборот, "не должен" должен толковаться как запрет.
Следовательно, строго соответствующая программа никогда не должна принимать размер функции. Но, опять же, он, вероятно, также должен использовать правильную форму main()
:-)
Однако здесь есть лазейка. Соответствующая реализация может предоставлять расширения "при условии, что они не изменяют поведение любой строго соответствующей программы" (раздел 4 Conformance
подраздел 6
).
Вы можете утверждать, что это изменение поведения (позволяя sizeof(function)
вместо того, чтобы запретить это), но, поскольку исходная программа не была бы строго соответствующей в первую очередь, подраздел не запрещает ее.