Это ошибка компилятора.
Первое, что нужно отметить: -2147483648 не является буквальным. В C ++ нет такой вещи, как отрицательный литерал.
-2147483648 - это константное выражение, оценивающее время компиляции, состоящее из 2147483648 и унарного оператора минуса.
В MSVC, ориентированном на Windows x64 ( где int и long являются 32 битами), 2147483648 должен быть long long int
, и поэтому так будет -2147483648. Я понимаю, что стандарт настаивает на на подписанном типе , если только вы не используете шестнадцатеричный или восьмеричный литерал.
Сужение преобразования в signed int
в этом случае, четко определен, так как вы нацеливаете платформу с 32-битным дополнением int
.
Дополнительная ссылка: см. http://en.cppreference.com/w / CPP / язык / integer_literal
Единственное время я когда-либо видел массивы нулевой длины, на самом деле используемые, - когда Вы хотите иметь структуру переменной длины.
Как в этом примере, взятом от здесь
struct line {
int length;
char contents[0];
};
struct line *thisline = (struct line *)
malloc (sizeof (struct line) + this_length);
thisline->length = this_length;
, Вы не хотите использовать указатель в вышеупомянутой структуре, как Вы хотите, чтобы содержание было частью выделенной памяти структуры.
, Если Вы делаете sizeof на вышеупомянутой структуре, она не включает пространства для содержания. Я не уверен, превращало ли это когда-нибудь его в стандарт, это дает предупреждения на различных компиляторах.
ISO C запрещает 0
- массивы длины.
char **c1;
Это определяет объект c1
из типа pointer-to-pointer-to-char.
char *c2[0];
Это - ошибка компиляции. Не позволенный. Не в C, не в C++.
struct a {
int i;
char c[0]; //sizeof(a) is sizeof(int)? a.c == (&i)+1?
};
Ошибка, как отмечено ранее - размер массива должен быть больше, чем нуль.
struct a {
int i;
char c[1];
};
Также известный как взлом структуры . Злоупотребленный в коде низкого уровня почти всех Ose - Linux, Windows.
C99 действительно дает нам массив без размера, более известный как участник массива с переменными границами:
struct a {
int i;
char c[]; /* note: no size */
};
Из стандарта C99 (7.20.3), имея дело с функциями выделения:
Каждое такое выделение должно привести к указателю на объект, непересекающийся от любого другого объекта.
[...]
, Если размер пространства, которое требуют, является нулем, поведение является определенной реализацией: или нулевой указатель возвращается, или поведение состоит в том, как будто размер был некоторым ненулевым значением, за исключением того, что возвращенный указатель не должен использоваться для доступа к объекту.
, Другими словами, в случае объявления b
на стеке без инициализатора (то, где b
, имеет c
объявленный как c[]
вместо c[0]
), фактический размер b
с точки зрения пространства, на самом деле использованного, будет> 0, так как Вы не можете получить доступ ни к какой части b
. Если это будет выделено через malloc
, то это будет или возвращено как 0
или как некоторое уникальное значение, к которому нельзя получить доступ (если Вы используете sizeof(b)
).