Чому sizeof називається оператором часу компіляції?


12

Спочатку це частина іншого питання.

Чому його sizeofназивають оператором часу компіляції? Це насправді оператор не працює? І якщо це дійсно оператор часу компіляції, як це допомагає створювати портативний код, який працює однаково на різних комп'ютерах? Будь ласка, поясніть детально.


4
детально відповіли на SO: Чому sizeof (x ++) не збільшується x?
гнат

3
Як ви очікуєте зміни розміру типу під час виконання?

@MichaelT: Розмір екземпляра типу, безумовно, може змінюватися - зрештою, є класовий поліморфізм. Я б заперечував, що sizeof(polymorphic_ptr*)бути постійним є досить протиінтуїтивним і просто нерозумним. Так, це спосіб С ++, але все-таки нерозумно.
Відновіть Моніку

@KubaOber Дійсно. Мені просто цікаво, як ОП вважала, що вона повинна вести себе в різних випадках, і, сподіваюся, отримаю якийсь код, який би демонстрував його плутанину щодо цього, щоб допомогти розширити питання.

4
Прийшов, щоб підтвердити відповідь "тому, що вона працює в час компіляції", залишився розчарованим.
Бен Джексон

Відповіді:


23

sizeof()дає розмір типу даних , а не розмір певного екземпляра цього типу в пам'яті.

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

Розмір типу даних завжди відомий під час компіляції.


3
Оскільки у C (++) немає метаданих об'єктів часу виконання, ви також не можете отримати ці речі під час виконання.
C. Ross

5
На насправді, якщо ви використовуєте sizeofна масиві, ви будете отримати розмір масиву (тобто раз розміру елемента числа елементів). Але якщо ви використовуєте його вказівник, ви отримуєте лише розмір вказівника. Отже, оскільки у більшості випадків, коли ви хочете знати розмір масиву, у вас є лише вказівник, це не все так корисно.
sepp2k

1
@Jens Питання позначено тегом [C ++], і VLA не перетворив його на стандарт C ++.
authchir

13

тому що весь розмір "виклику" обчислюється під час компіляції, і все, що знаходиться між дужками, відкидається і не виконується під час виконання,

результат грунтується лише на інформації статичного типу, доступній компілятору


7

Чому sizeof називається оператором часу компіляції?

Тому що, під час компіляції, компілятор обчислює розмір виразу та підміняє постійне значення часу компіляції.

Це насправді оператор не працює?

Ні. Ви навіть можете використовувати sizeofдля оцінки розміру виразів, які ви не можете законно виконати (тобто, це спричинило б невизначене поведінку), доки компілятор може з'ясувати, який тип виразу.

Крім того, навіть перед C ++ 11 constexprви можете використовувати sizeofвирази способами, якими ви не можете використовувати вирази часу виконання.

І якщо це дійсно оператор часу компіляції, як це допомагає у створенні портативного коду ...

Типи можуть відрізнятися за розмірами на різних платформах. Використання sizeofвиразів замість твердо кодованих припущень означає, що ваш код не зламається, коли ви збираєтеся на іншій платформі, а ваші типи змінюють розмір.


1
Ну, я вважаю це найкориснішою відповіддю;). Брат (якщо вважати, що ти чоловік), я маю сумніви. Ви хочете сказати, що коли люди кажуть, що sizeof робить програми портативними, вони означають, що вихідний код може бути скомпільований без будь-яких помилок на всіх машинах, і вони не означають, що виконувана програма може працювати в будь-якій машині. Правильно? Якщо це правильно, мої сумніви справді очищаються.
Мирний кодер

1
Так, код портативний, в тому сенсі ви можете скласти (різні) правильні двійкові файли для кожної платформи.
Марно

5

C ++ насправді не зберігає метадані для об’єктів під час виконання, тому перевірка розміру повинна бути складеною часом. Для прикладу того, як C ++ не підтверджує розмір, оголосити масив intякогось довільного розміру і прочитати минулий кінець його. Якщо вам пощастить, ви отримаєте, segfaultале, швидше за все, ви просто прочитаєте хитрість, оскільки C ++ не відстежує розмір вашого масиву.

Див. Чи може програма C / C ++ виправляти помилки при читанні минулого кінця масиву (UNIX)? для прикладу з SO.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.