Когда мы проверяем размер функции с помощью sizeof()
, мы всегда получаем 1 байт . Что означает этот 1 байт?
87
Это нарушение ограничения, и ваш компилятор должен его диагностировать. Если он компилирует его, несмотря на это, ваша программа имеет неопределенное поведение [спасибо @Steve Jessop за разъяснение режима отказа и см. Ответ @Michael Burr о том, почему некоторые компиляторы допускают это]: из C11, 6.5.3.4./ 1:
sizeof
Оператор не должен быть применен к выражению , которое имеет тип функции
-pedantic
), значит, у вас несовместимый компилятор, и каждая программа имеет неопределенное поведение.-std=c11
, а неgnu11
. Это действительно странное расширение компилятора.sizeof(void)
как 1 в GNU C.-std=c11
: кто-то должен сослаться на-std=c*
варианты в Стандарты рекламы. Они не включают режим соответствия, они просто отключают расширения, которые могут помешать компиляции правильно сформированной программы (например,typeof
быть ключевым словом, поскольку правильно сформированная программа на C может использовать его как имя переменной, ноgcc
по умолчанию отклоняет это ). Чтобы дополнительно отключить расширения, которые позволяют плохо сформированным программам проходить без диагностики, вам понадобится-pedantic
или-pedantic-errors
.Это не неопределенное поведение - стандарт языка C требует диагностики при использовании
sizeof
оператора с указателем функции (именем функции), поскольку это нарушение ограничения дляsizeof
оператора.Однако, как расширение языка C, GCC позволяет выполнять арифметические операции с
void
указателями и указателями функций, что достигается путем обработки размера avoid
или функции как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
к указателю на функцию.