2013-09-12 1 views
3

Мой компилятор является последним предварительным просмотром VC++ 2013.Почему выражение sizeof не является константой времени компиляции, как 2, 4, 8 и т. Д.?

int main() 
{ 
    __declspec(align(4))   int n1 = 0; // OK. 
    __declspec(align(sizeof(int))) int n2 = 0; // error C2059: syntax error : 'sizeof' 
} 

Почему выражение SizeOf не компиляции постоянная времени, как 2, 4, 8 и т.д.?

+0

В нем говорится «синтаксическая ошибка», поэтому, возможно, синтаксический анализатор ожидает числовую константу. На моей машине unix "int a [sizeof (int)];" на глобальном уровне компилируется нормально. –

+7

Материал '__declspec' - это специальный синтаксис расширения MSVC, для которого у них есть набор [туманных правил] (http://msdn.microsoft.com/en-us/library/dabb5z75.aspx), и, очевидно, это не подлежащих стандартным правилам. В этом смысле я не думаю, что важно, является ли sizeof() 'константой времени компиляции или нет, потому что я думаю, что эти расширения обрабатываются вне остальной части компиляции (т. Е. Что-то между MACRO и правильная конструкция C++).Короче говоря, MSVC делает свои собственные правила здесь, и вам просто нужно жить с ними, если ему не нравится 'sizeof()', то вы не можете его там использовать. –

+2

Похоже, что MS определяет оператор ['__alignof'] (http://msdn.microsoft.com/en-us/library/45t0s5f4.aspx) точно так, как вам кажется. Для простых типов он аналогичен 'sizeof', но он ведет себя несколько иначе для сложных типов, таких как structs и т. Д. – torak

ответ

0

В C Стандартная

The SizeOf оператор не должен быть применен к выражению, которое имеет тип функции или неполный тип, в скобках имя такого типа или к выражение, которое обозначает член битового поля. Оператор _Alignof не применяется к типу функции или к неполному типу.

Оператор sizeof дает размер (в байтах) своего операнда, который может быть выражением или заключенным в скобки именем типа. Размер определяется по типу операнда. Результат - целое число. Если тип операнда представляет собой тип массива переменной длины, оценивается операнд ; в противном случае операнд не оценивается, а результат является целочисленной константой.

+0

Как это полезно здесь? Мы даже не говорим о C, но C++, и проблема возникает из-за расширения MSVC, а не стандарта. – pmr

4

Вместо того, чтобы спрашивать: Почему выражение SizeOf не время компиляции постоянной, как 2, 4, 8 и т.д.?

(потому что, на самом деле, это является компиляцией постоянного времени так же, как эти примеры (:. Запрещая массивы переменной длиной из более новых стандартов C, для которых он должен быть выражением времени выполнения :))

Лучше спросить: Почему align(...) не принимает константу времени компиляции, такую ​​как выражение sizeof?

Microsoft определено __declspec(align(#)) только принять небольшой набор значений: См:. https://msdn.microsoft.com/en-us/library/83ythb65.aspx

«# это значение выравнивания Допустимые значения являются целыми степенями двойки от 1 до 8192 (байт) , таких как 2, 4, 8, 16, 32 или 64. "

Так что даже с простыми константами допускается не только любое значение. __declspec(align(7)) не допускается, так как это не сила 2. Даже простые выражения, такие как __declspec(align(4+4)) не допускаются.