Annex C (informative) Compatibility [diff]

C.1 C++ and ISO C [diff.iso]

C.1.8 Clause [class]: classes [diff.class]

[class.name] [см. также [dcl.typedef]]
Изменение: В C ++ объявление класса вводит имя класса в область, в которой он объявлен, и скрывает любой объект, функцию или другое объявление с этим именем во включающей области. В C объявление внутренней области видимости имени тега структуры никогда не скрывает имя объекта или функции во внешней области.

Пример:

int x[99];
void f() {
  struct x { int a; };
  sizeof(x);  /* size of the array in C */
  /* size of the struct in C++ */
}


Обоснование: это одна из немногих несовместимостей между C и C ++, которая может быть отнесена к новому определению пространства имен C ++, где имя может быть объявлено как тип и как не-тип в одной области, в результате чего имя, не являющееся типом, становится скрыть имя типа и требует, чтобы ключевые слова class, struct, union или enum использоваться для обозначения имени типа. Это новое определение пространства имен обеспечивает важные нотационные удобства для программистов на C ++ и помогает сделать использование определяемых пользователем типов как можно более похожим на использование фундаментальных типов. Было сочтено, что преимущества нового определения пространства имен намного перевешивают несовместимость с C, описанным выше.
Влияние на исходную функцию: изменение семантики четко определенной функции.
Сложность преобразования: семантическое преобразование. Если скрытое имя, к которому необходимо получить доступ, находится в глобальной области видимости, ​::​ можно использовать оператор C ++. Если скрытое имя находится в области видимости блока, необходимо переименовать тип или тег структуры.
Насколько широко используется: редко.

[class.bit]
Изменение: Подписаны битовые поля типа plain int .
Обоснование: оставление выбора подписи на усмотрение реализаций может привести к несогласованным определениям специализаций шаблонов. Для согласованности также была исключена свобода реализации для независимых типов.
Влияние на исходную функцию: выбор определяется реализацией в C, но не в C ++.
Сложность преобразования: синтаксическое преобразование.
Насколько широко используется: редко.

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

Пример:

struct X {
  struct Y { /* ... */ } y;
};
struct Y yy;                    // valid C, invalid C++


Обоснование: классы C ++ имеют функции-члены, которые требуют, чтобы классы устанавливали области действия. Правило C оставит классы как механизм неполной области видимости, который не позволит программистам на C ++ поддерживать локальность внутри класса. Согласованный набор правил области видимости для C ++, основанный на правиле C, был бы очень сложным, и программисты на C ++ не смогли бы надежно предсказать значения нетривиальных примеров, включающих вложенные или локальные функции.
Влияние на исходную функцию: изменение семантики четко определенной функции.
Сложность преобразования: семантическое преобразование. Чтобы сделать имя типа структуры видимым в области охватывающей структуры, тег структуры может быть объявлен в области охватывающей структуры до того, как будет определена включающая структура. Пример:

struct Y;                       // struct Y and struct X are at the same scope
struct X {
  struct Y { /* ... */ } y;
};

Все определения типов структур C, заключенные в другие определения структур и доступные за пределами области действия включающей структуры, могут быть экспортированы в область действия включающей структуры. Примечание: это следствие разницы в правилах области видимости, которая задокументирована в [basic.scope].
Насколько широко используется: редко.

[class.nested.type]
Изменение: В C ++ имя typedef не может быть повторно объявлено в определении класса после использования в этом определении.

Пример:

typedef int I;
struct S {
  I i;
  int I;                  // valid C, invalid C++
};


Обоснование: когда классы усложняются, разрешение такого переопределения после использования типа может создать путаницу для программистов на C ++ относительно того, что на I самом деле означает.
Влияние на исходный объект: удаление семантически четко определенного объекта.
Сложность преобразования: семантическое преобразование. Необходимо переименовать тип или член структуры.
Насколько широко используется: редко.