Сопоставление символа внутренней и внешней структур, С++ vs C

Итак, скажем, у меня есть следующий заголовок С++, testheader.h:

struct mystruct
{
  struct myinnerstruct
  {
        int x;
  } astruct;
};

struct myinnerstruct
{
    int x;
};

и следующий источник С++, test.cpp:

#include "testheader.h"
using namespace std;
int main()
{
    return 0;
}

g++ не дает проблем во время компиляции/ссылки.

Теперь, если у меня есть тот же заголовок, но вместо источника С++ исходный файл C test.c:

#include "testheader.h"
int main()
{
  return 0;
}

И компилирую с gcc, я получаю следующую ошибку:

error: redefinition of struct myinnerstruct

Итак, я понимаю, что область действия версии C является единицей перевода, а версия С++ - блочной областью? Может ли кто-то подтвердить, что это так, и, возможно, объяснить мне, почему это имеет смысл? Я делаю некоторое смешивание кода C и С++, и это дает мне немного неприятностей.

Любое понимание очень ценится. Спасибо!

Ответ 1

В C вложенных структурах фактически не живут в пределах их родителей. Однако в С++ они do- teststruct::innerstruct относятся к типу innerstruct. Это делается для улучшения инкапсуляции кода С++. Без этого правила никакие два типа в одном и том же пространстве имен не могли бы определить, например, вложенный класс iterator, что было бы очень плохо.

C обрабатывает структуры множеством других очень глупых способов, поэтому неудивительно, что они сделали не то, что здесь произошло. Тем не менее, C в противном случае не допускает определение типа и правильное правило, которое должно было ввести множество дополнительных понятий для языка - в конечном итоге потребовалось бы введение namespace s, которое по какой-то причине не было выполнено.

Ответ 2

В C определение внутренней структуры выходит за пределы внешней структуры, что не имеет места в С++.

Это объяснено в этом блоге: Несовместимость между ISO C и ISO С++ среди многих других в C против С++ с ссылкой на стандарты ISO C99 и С++ 98.

Ответ 3

В C нет областей, поэтому все находится в "глобальном" пространстве имен (на языке С++)

Ответ 4

Более чистый способ, который работает в боте C и С++:

struct myinnerstruct
{
    int x;
};

struct mystruct
{
  struct myinnerstruct astruct;
};