Почему это разное поведение инициализации структуры в C и C ++? - PullRequest
0 голосов
/ 21 ноября 2018

Код:

#include <stdio.h>

typedef struct{
  int i;
  int tab[];
}mystr;

mystr a = {1,{0,1,2}};

int main(void){
  printf("%d%d%d\n",a.i,a.tab[0],a.tab[1]);
  return 0;
}

C компиляция:

$ gcc main.c -o main && ./main
101

C ++ компиляция:

$ g++ main.c -o main && ./main
main.c:8:27: error: too many initializers for ‘int [0]’
 const mystr a = {1,{0,1,2}};
                           ^

Я понимаю проблему, это то, что tabне выделено никакой памяти.Но почему это нормально для C?Почему C ++ не выделяет автоматически пространство памяти для tab?Я знаю, что структуры похожи на объекты в C ++, но, может быть, есть некоторые тонкости, которые я не знаю о создании глобальных объектов?

Ответы [ 2 ]

0 голосов
/ 21 ноября 2018

Все в поднятом ответе может быть точным, но оно танцует вокруг корня вашего вопроса.Вы абсолютно правы - на образах Debian и Alpine Docker, и вызов gcc, который не включает -pedantic, компилирует и запускает его без жалоб:

root@45c9da7956c8:/# cat t.c; gcc -std=c11 -o t t.c && ./t;
#include <stdio.h>

typedef struct{
  int i;
  int tab[];
}mystr;

mystr a = {1,{0,1,2}};

int main(void){
  printf("%d%d%d\n",a.i,a.tab[0],a.tab[1]);
  return 0;
}
101

Gcc - очень удобный компилятор,и будет работать с вещами, которые могут быть точно описаны как не соответствующие спецификации.Это не обязательно делает его плохим компилятором - но это делает его плохим тестом на соответствие кода стандартам.-pedantic поможет с этим.

Я повторю замечание, высказанное в комментариях к вопросу, что в концептуальном отношении лучше всего думать о C и C ++ как о совершенно разных языках.По крайней мере, я не могу вспомнить случай, когда получение кода C для компиляции на компиляторе c ++ имело бы какое-либо значение.Думая о них как о совершенно отдельном, это верная модель того, как они действуют в реальной жизни.

0 голосов
/ 21 ноября 2018

Код недопустим в C. Это не разрешено в C

typedef struct{
  int i;
  int tab[];
}mystr;

mystr a = {1,{0,1,2}};

Любое поведение, которое вы наблюдаете в режиме C, является причудой вашего компилятора, который не имеет ничего общего с языком.Компилятор поддерживает код как нестандартную функцию, расширение .

Ваш код также недопустим в C ++, но по причине, которая полностью отличается от той, о которой сообщил ваш компилятор,В C ++ вам не разрешено иметь массивы [] в качестве членов класса вообще.Компилятор пропускает его (как расширение снова), но позже терпит неудачу в другом месте.

Итак, ответ на ваш вопрос будет таким: используемый вами компилятор имеет разные причуды/ расширения в режиме C, чем в режиме C ++.Что неудивительно, так как это очень разные языки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...