Когда мы проверяем размер функции с помощью sizeof(), мы всегда получаем 1 байт . Что означает этот 1 байт?
Когда мы проверяем размер функции с помощью sizeof(), мы всегда получаем 1 байт . Что означает этот 1 байт?
Ответы:
Это нарушение ограничения, и ваш компилятор должен его диагностировать. Если он компилирует его, несмотря на это, ваша программа имеет неопределенное поведение [спасибо @Steve Jessop за разъяснение режима отказа и см. Ответ @Michael Burr о том, почему некоторые компиляторы допускают это]: из C11, 6.5.3.4./ 1:
sizeofОператор не должен быть применен к выражению , которое имеет тип функции
-std=c11, а не gnu11 . Это действительно странное расширение компилятора.
sizeof(void)как 1 в GNU C.
-std=c11: кто-то должен сослаться на -std=c*варианты в Стандарты рекламы. Они не включают режим соответствия, они просто отключают расширения, которые могут помешать компиляции правильно сформированной программы (например, typeofбыть ключевым словом, поскольку правильно сформированная программа на C может использовать его как имя переменной, но gccпо умолчанию отклоняет это ). Чтобы дополнительно отключить расширения, которые позволяют плохо сформированным программам проходить без диагностики, вам понадобится -pedanticили -pedantic-errors.
Это не неопределенное поведение - стандарт языка C требует диагностики при использовании sizeofоператора с указателем функции (именем функции), поскольку это нарушение ограничения для sizeofоператора.
Однако, как расширение языка C, GCC позволяет выполнять арифметические операции с voidуказателями и указателями функций, что достигается путем обработки размера a voidили функции как 1. Как следствие, sizeofоператор вычислит 1для voidили функцию с GCC. См. Http://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html#Pointer-Arith
Вы можете заставить GCC выдавать предупреждение при использовании sizeofс этими операндами, используя опции -pedanticили -Wpointer-arithдля GCC. Или сделайте ошибку с помощью -Werror=pointer-arith.
sizeofговорил о UB, за исключением того, что функция не является UB (о чем я упоминал в значительной степени только потому, что в других ответах говорилось, что это UB). Но, возможно, я запутал это из-за того, как я построил предложение. Чтобы было понятнее. sizeofфункция не является UB (как утверждается в нескольких ответах). Это нарушение ограничения. Таким образом, требуется диагностика. GCC разрешает это как расширение.
Это означает, что автор компилятора выбрал значение 1 вместо того, чтобы заставить демонов летать из вашего носа (действительно, это было еще одно неопределенное использование, sizeofкоторое дало нам это выражение: «сам компилятор C ДОЛЖЕН выдать диагностику, ЕСЛИ это первое требование диагностика в результате вашей программы, а затем МОЖЕТ сама вызвать демонов, вылетающих из вашего носа (что, кстати, вполне может БЫТЬ документированным диагностическим сообщением), точно так же, как МОЖЕТ выдать дополнительную диагностику для дальнейших нарушений синтаксических правил или ограничений (или, в этом отношении, по любой причине, которую он выберет). " https://groups.google.com/forum/?fromgroups=#!msg/comp.std.c/ycpVKxTZkgw/S2hHdTbv4d8J
Отсюда есть жаргонный термин «назальные демоны» для обозначения того, что компилятор решает сделать в ответ на неопределенную конструкцию. 1- назальный демон этого компилятора для этого случая.
Как указывали другие, sizeof () может принимать любой действительный идентификатор, но он не возвращает действительный (честно истинный и действительный) результат для имен функций. Кроме того, это определенно может или не может привести к синдрому «демонов из носа».
Если вы хотите профилировать размер функции вашей программы, проверьте карту компоновщика, которую можно найти в каталоге промежуточных результатов (тот, где вещи компилируются в .obj / .o или где находится результирующее изображение / исполняемый файл). Иногда есть возможность сгенерировать или нет этот файл карты ... он зависит от компилятора / компоновщика.
Если вам нужен размер указателя на функцию, все они имеют одинаковый размер, размер адресного слова на вашем процессоре.
int x = 1;но только один из них разрешен для компилятора, совместимого со стандартами. При sizeof()применении к функции он может или не может возвращать установленное значение, или отказываться от компиляции, или возвращать случайное значение, основанное на том, что находится в конкретном регистре в то время. Буквальные носовые демоны маловероятны, но в пределах буквы стандарта.
sizeofк указателю на функцию.
-pedantic), значит, у вас несовместимый компилятор, и каждая программа имеет неопределенное поведение.