Декларація проти визначення

код:

  int main()
      {
        extern int a;
        int b;
        cout<<<<

вихід:

4
4

Якщо ми просто оголошуємо змінну, вона не повинна виділяти пам'ять для цієї змінної (?). Так як компілятор не дасть помилку

 cout<<

або чому програма не розбивається?

0
Тип визначає розмір об'єкта. Коли ви виконуєте int a; , він повідомляє компілятору: "відмінити 4 байти інформації для вхідного цілого числа".
додано Автор 0x499602D2, джерело
Крім того, sizeof не оцінює його операнд, тому поведінка визначена.
додано Автор 0x499602D2, джерело
sizeof працює під час компіляції, а не час запуску.
додано Автор Ed S., джерело

6 Відповіді

sizeof не потрібно оцінювати вираз, який ви передаєте йому, тільки його тип. Зовнішнє визначення extern int a достатньо для з'ясування типу, тому sizeof вдається.

Крім того, оскільки вираз в межах sizeof не оцінюється, програма зв'язує без помилки.

4
додано

sizeof is resolved at compile time. All the compiler needs is a declaration with a complete type – it does not need to allocate storage for the object.

Оскільки вираз sizeof вирішується під час компіляції, тому не перевіряється , чи дійсно об'єкт визначено в іншій одиниці компіляції. Якщо ми хотіли за допомогою цієї перевірки, ми не змогли оцінити sizeof під час компіляції (нам доведеться відкласти це час посилання), і немає простої причини для цієї затримки .

3
додано

sizeof() - це не функція, це ключове слово мови, яке вирішує константу часу компіляції.

Отже, ви не отримуєте доступу або використовуєте "a", а ви запитуєте компілятора питання про одну з частин інформації, яку ви надали йому про "a".

cout << sizeof( a ) << endl:

насправді

cout << sizeof decltype(a) << endl;

насправді

cout << sizeof int << endl;

насправді

cout << 4 << endl;

Ви можете перевірити це, подивившись на випуск збірки. Під Linux, з GCC або Clang

c++ -Wall -o test.S -S test.cpp

буде генерувати файл збірки для перевірки.

2
додано

Компілятор знає, що розмір int має розмір 4, і нічого, що ніколи не може дати int іншого розміру після складання. Через це sizeof (a) стає sizeof (int) , який стає 4 .

2
додано

Оскільки він отримує розмір типу змінної, а не фактичної використовуваної пам'яті (вона повинна бути однаковою).

int main() {
    int a = 2;

    std::cout << sizeof ((char) a) << std::endl;//Outputs 1

    return 0;
}
1
додано

З extern int a ви просто повідомляєте компілятору, що існує (мабуть,) де-небудь змінну з назвою a типу int . Однак єдине, що вам потрібно зробити - це застосувати до нього код sizeof . Тепер для компілятора не потрібно мати доступ до a , щоб знати його розмір: оскільки ви сказали компілятору, що a має тип int , він вже знає його розмір: всі int s мають однаковий розмір.

Чому компілятор не дає помилку: відсутнє визначення для об'єкта extern дає помилку, лише якщо цей об'єкт фактично використовується. Оскільки sizeof не використовує його, а лише розповідає вам розмір, ви не отримаєте помилку компілятора.

1
додано
IT KPI C/С++ новым годом
IT KPI C/С++ новым годом
747 учасників

Чат обсуждения С/С++. - Вопросы "напишите за меня лабу" - это оффтоп. - Оффтоп, флуд, оскорбления и вбросы здесь не приняты. - За нарушение - предупреждение или mute на неделю. - За спам и рекламу - ban. Все чаты IT KPI: https://t.me/itkpi/1147