Коли ми перевіряємо розмір функції за допомогою 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
Ви можете отримати ПКУ видавати попередження при використанні sizeof
з цими операндами, використовуючи -pedantic
або -Wpointer-arith
варіанту GCC. Або зробіть помилку з -Werror=pointer-arith
.
sizeof
говорив про UB, окрім того, що функція не є UB (про що я згадав майже лише тому, що інші відповіді стверджували, що це UB). Але, можливо, я заплутав це через те, як я структурував речення. Щоб бути більш чітким. sizeof
функція не є UB (як стверджували кілька відповідей). Це порушення обмеження. Як такий, він вимагає діагностики. GCC дозволяє це продовження.
Це означає, що автор компілятора визначився із значенням 1, а не змусив демонів злітати з носа (справді, це було черговим невизначеним використанням sizeof
дало нам такий вираз: "сам компілятор С ПОВИНЕН видати діагностику, ЯКЩО це перше, що потрібно діагностика, отримана в результаті вашої програми, а потім МОЖЕ привести до того, що демони вилітають з вашого носа (що, до речі, цілком може бути документальним діагностичним повідомленням), так само, як МОЖЕ видати подальшу діагностику щодо подальших порушень правил синтаксису або обмежень (або, з цього приводу з будь-якої причини). " https://groups.google.com/forum/?fromgroups=#!msg/comp.std.c/ycpVKxTZkgw/S2hHdTbv4d8J
З цього випливає жаргонний термін "носові демони" для того, що компілятор вирішить зробити у відповідь на невизначену конструкцію. 1
є носовим демоном цього компілятора для цієї справи.
Як зазначали інші, sizeof () може приймати будь-який дійсний ідентифікатор, але він не повертає дійсний (чесно істинний та дійсний) результат для імен функцій. Більше того, це, безумовно, може призвести чи не призвести до синдрому "демонів з носа".
Якщо ви хочете профайлювати розмір вашої програми, перевірте карту зв’язку, яку можна знайти в каталозі проміжних результатів (тому, де речі компілюються в .obj / .o, або де лежить отримане зображення / виконуваний файл). Іноді існує можливість згенерувати цей файл карти чи ні ... це залежить від компілятора / лінкера.
Якщо вам потрібен розмір вказівника на функцію, вони мають однаковий розмір, розмір адресного слова на вашому процесорі.
int x = 1;
але для компілятора, що відповідає стандартам, допускається лише один із них. Сsizeof()
застосовуються до функції, він може або не може повертати задане значення, або відмовитися від компіляції, або повертає випадкове значення , засноване на те , що це в певному регістрі в той час. Буквальні носові демони малоймовірні, але в межах букви стандарту.
sizeof
до вказівника на функцію.
-pedantic
), у вас є невідповідний компілятор, і кожна програма має невизначену поведінку.