[dcl.stc]
Изменение: В C ++ спецификаторы static или extern могут применяться только к именам объектов или функций.
Использование этих спецификаторов с объявлениями типов недопустимо в C ++. В C эти спецификаторы игнорируются при использовании в объявлениях типов.
Пример:
static struct S { // valid C, invalid in C++
int i;
};
Обоснование:
спецификаторы класса хранилища не имеют никакого значения, когда они связаны с типом. В C ++ члены класса могут быть объявлены с помощью static спецификатора класса хранения. Разрешение указателей класса хранения в объявлениях типов может сбить с толку пользователей.
Влияние на исходный объект:
удаление семантически четко определенного объекта.
Сложность преобразования:
синтаксическое преобразование.
Насколько широко используется:
редко.
[dcl.stc]
Изменение: в C ++ register не является спецификатором класса хранения.
Обоснование:
спецификатор класса хранения не действует в C ++.
Влияние на исходный объект:
удаление семантически четко определенного объекта.
Сложность преобразования:
синтаксическое преобразование.
Насколько широко используется:
Обычный.
[dcl.typedef]
Изменение: имя typedef C ++ должно отличаться от любого имени типа класса, объявленного в той же области (кроме случаев, когда typedef является синонимом имени класса с тем же именем). В C имя typedef и имя тега структуры, объявленные в одной области, могут иметь одно и то же имя (потому что у них разные пространства имен).
Пример:
typedef struct name1 { /* ... */ } name1; // valid C and C++ struct name { /* ... */ }; typedef int name; // valid C, invalid C++
Обоснование:
Для простоты использования, C ++ не требует , чтобы имя типа с префиксом ключевых слов class, struct или union при использовании в объявлениях объектов или слепков типа.
Пример:
class name { /* ... */ }; name i; // i has type class name
Влияние на исходный объект:
удаление семантически четко определенного объекта.
Сложность преобразования:
семантическое преобразование. Необходимо переименовать один из двух типов.
Насколько широко используется:
редко.
[dcl.type] [см. также [basic.link]]
Изменение: const объекты должны быть инициализированы в C ++, но могут быть оставлены неинициализированными в C.
Обоснование:
объект const не может быть назначен, поэтому он должен быть инициализирован для хранения полезного значения.
Влияние на исходный объект:
удаление семантически четко определенного объекта.
Сложность преобразования:
семантическое преобразование.
Насколько широко используется:
редко.
[dcl.type]
Изменение: неявный запрет int.
В C ++ a decl-specifier-seq должен содержать a type-specifier, если за ним не следует декларатор для конструктора, деструктора или функции преобразования. В следующем примере в левом столбце представлен действительный C; в правом столбце представлен эквивалентный C ++:
void f(const parm); void f(const int parm); const n = 3; const int n = 3; main() int main() /* ... */ /* ... */
Обоснование:
В C ++ неявное int создает несколько возможностей для двусмысленности между выражениями, включающими функционально-подобные приведения и объявления. Явное объявление все чаще считается правильным стилем. Связь с WG14 (C) указала на поддержку (по крайней мере) отказа от неявного int в следующей версии C.
Влияние на исходную функцию:
удаление семантически четко определенной функции.
Сложность преобразования:
синтаксическое преобразование. Можно автоматизировать.
Насколько широко используется:
Обычный.
[dcl.spec.auto]
Изменение:
ключевое слово auto нельзя использовать в качестве спецификатора класса хранения.
void f() {
auto int x; // valid C, invalid C++
}
Обоснование: разрешение использовать auto для определения типа переменной из ее инициализатора приводит к нежелательной интерпретации
auto в качестве спецификатора класса хранения в определенных контекстах.
Влияние на исходный объект: удаление семантически четко определенного объекта.
Сложность преобразования: синтаксическое преобразование.
Насколько широко используется: редко.
[dcl.enum]
Изменение: объектам C ++ перечислимого типа могут быть присвоены значения только одного и того же перечислимого типа. В C объектам перечислимого типа могут быть присвоены значения любого целочисленного типа.
Пример:
enum color { red, blue, green };
enum color c = 1; // valid C, invalid C++
Обоснование:
типобезопасная природа C ++.
Влияние на исходный объект:
удаление семантически четко определенного объекта.
Сложность преобразования:
синтаксическое преобразование. (Ошибка типа, вызванная назначением, может быть автоматически исправлена путем применения явного приведения.)
Насколько широко используется:
Часто.
[dcl.enum]
Изменение: В C ++ тип перечислителя - это его перечисление. В C тип перечислителя int.
Пример:
enum e { A }; sizeof(A) == sizeof(int) // in C sizeof(A) == sizeof(e) // in C++ /* and sizeof(int) is not necessarily equal to sizeof(e) */
Обоснование:
В C ++ перечисление - это отдельный тип.
Влияние на исходную функцию:
изменение семантики четко определенной функции.
Сложность преобразования:
семантическое преобразование.
Насколько широко используется:
редко. Единственный раз, когда это влияет на существующий код C, - это когда берется размер перечислителя. Взятие размера перечислителя - не обычная практика кодирования C.