нулевая длина выстраивает по сравнению с указателями

Это ошибка компилятора.

Первое, что нужно отметить: -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

21
задан jdizzle 9 March 2009 в 19:49
поделиться

3 ответа

Единственное время я когда-либо видел массивы нулевой длины, на самом деле используемые, - когда Вы хотите иметь структуру переменной длины.

Как в этом примере, взятом от здесь

    struct line {
       int length;
       char contents[0];
     };

     struct line *thisline = (struct line *)
       malloc (sizeof (struct line) + this_length);
     thisline->length = this_length;

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

, Если Вы делаете sizeof на вышеупомянутой структуре, она не включает пространства для содержания. Я не уверен, превращало ли это когда-нибудь его в стандарт, это дает предупреждения на различных компиляторах.

12
ответ дан 29 November 2019 в 21:44
поделиться

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 */ 
};
9
ответ дан 29 November 2019 в 21:44
поделиться

Из стандарта C99 (7.20.3), имея дело с функциями выделения:

Каждое такое выделение должно привести к указателю на объект, непересекающийся от любого другого объекта.

[...]

, Если размер пространства, которое требуют, является нулем, поведение является определенной реализацией: или нулевой указатель возвращается, или поведение состоит в том, как будто размер был некоторым ненулевым значением, за исключением того, что возвращенный указатель не должен использоваться для доступа к объекту.

, Другими словами, в случае объявления b на стеке без инициализатора (то, где b, имеет c объявленный как c[] вместо c[0]), фактический размер b с точки зрения пространства, на самом деле использованного, будет> 0, так как Вы не можете получить доступ ни к какой части b. Если это будет выделено через malloc, то это будет или возвращено как 0 или как некоторое уникальное значение, к которому нельзя получить доступ (если Вы используете sizeof(b)).

1
ответ дан 29 November 2019 в 21:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: