Законно ли создание гибкого элемента массива нулевого размера? - PullRequest
1 голос
/ 18 февраля 2011

Стандарт C99 позволяет создавать элементы гибкого массива, такие как

typedef struct pstring {
  size_t length;
  char   string[];
} pstring;

. Затем он инициализируется чем-то вроде pstring* s = malloc(sizeof(pstring) + len).Допустимо ли для len быть ноль?Казалось бы, это согласованно, и было бы неплохо время от времени экономить место (вероятно, не с примером pstring, конечно).С другой стороны, я понятия не имею, что будет делать следующий код:

pstring* s = malloc(sizeof(pstring));
s->string;

Это также похоже на то, что может работать с одним компилятором, а не с другим, или с одной ОС, а не с другойили в один день, а не в другой, поэтому я действительно хочу узнать, что об этом говорит стандарт .Это malloc в примере кода с неопределенным поведением, или это только доступ к s->string, который является недопустимым, или это что-то совсем другое?

Ответы [ 2 ]

6 голосов
/ 18 февраля 2011

То, что вы делаете, допустимо, но доступ к s-> string [0] или подача s-> string к любой функции, обращающейся к данным, недопустим.

Стандарт C99 фактически говорит (§6.7.2.1):

struct s { int n; double d[]; };

...

struct s t1 = { 0 }; // valid

...

Назначение t1.d[0], вероятно, является неопределенным поведением, но возможно, что

sizeof (struct s) >= offsetof(struct s, d) + sizeof (double)

в этом случае присвоение будет законным.Тем не менее, он не может появляться в строго соответствующем коде.

1 голос
/ 18 февраля 2011

В свое время Microsoft C разрешил следующее:

struct pstring {
  size_t length;
  char string[0];
};

И я использовал нечто подобное для создания текстового редактора.Однако это было давно, и я знаю, что это было нестандартно в то время.Я даже не уверен на 100%, что Microsoft все еще поддерживает это.

Суть в том, что это зависит от вашего компилятора и текущих настроек компиляции.

...