Annex C (informative) Compatibility [diff]

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

В этом подпункте перечислены различия между C ++ и ISO C по главам этого документа.

C.1.1 Clause [lex]: lexical conventions [diff.lex]

[lex.key]
Изменение: новые ключевые
слова В C ++ добавлены новые ключевые слова; см [lex.key].
Обоснование: эти ключевые слова были добавлены для реализации новой семантики C ++.
Влияние на исходную функцию: изменение семантики четко определенной функции. Любые программы ISO C, которые использовали любое из этих ключевых слов в качестве идентификаторов, не являются допустимыми программами C ++.
Сложность преобразования: синтаксическое преобразование. Преобразовать одну конкретную программу очень просто. Преобразование большого набора связанных программ требует больше работы.
Насколько широко используется: Обычный.

[lex.ccon]
Изменение: Тип символьного литерала изменен с int на char.
Обоснование: это необходимо для улучшенного сопоставления типов аргументов перегруженной функции. Например:

int function( int i );
int function( char c );

function( 'x' );

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

sizeof('x') == sizeof(int)

не будет работать так же, как программы на C ++.
Сложность конвертации: Простая.
Насколько широко используется: Зависящие от sizeof('x') него программы, вероятно, встречаются редко.

Подпункт [lex.string]:
Изменение: строковые литералы сделаны константными.
Тип строкового литерала изменяется с «массив char» на «массив из const char». Тип char16_­t строкового литерала изменяется с «массив some-integer-type» на «массив из const char16_­t». Тип char32_­t строкового литерала изменяется с «массив some-integer-type» на «массив из const char32_­t». Тип широкого строкового литерала изменяется с «массив wchar_­t» на «массив из const wchar_­t».
Обоснование: это позволяет избежать вызова несоответствующей перегруженной функции, которая может рассчитывать на изменение своего аргумента.
Влияние на исходную функцию: изменение семантики четко определенной функции.
Сложность преобразования: синтаксическое преобразование. Исправление состоит в том, чтобы добавить приведение:

char* p = "abc";                // valid in C, invalid in C++
void f(char*) {
  char* p = (char*)"abc";       // OK: cast added
  f(p);
  f((char*)"def");              // OK: cast added
}


Насколько широко используется: программы, у которых есть законные основания рассматривать строковые литералы как указатели на потенциально изменяемую память, вероятно, встречаются редко.

C.1.2 Clause [basic]: basic concepts [diff.basic]

[basic.def]
Изменение: C ++ не имеет «предварительных определений», как в C.
Например, в области видимости файла,

int i;
int i;

допустимо в C, недопустимо в C ++. Это делает невозможным определение взаимно ссылочных локальных статических объектов файла, если инициализаторы ограничены синтаксическими формами C.Например,

struct X { int i; struct X* next; };

static struct X a;
static struct X b = { 0, &a };
static struct X a = { 1, &b };


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

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

[basic.link] [также [dcl.type]]
Изменение: имя области видимости файла, которое явно объявлено const, а не объявлено явно extern, имеет внутреннюю связь, тогда как в C оно будет иметь внешнюю связь.
Обоснование: поскольку const объекты могут использоваться в качестве значений во время трансляции в C ++, эта функция побуждает программистов предоставлять явный инициализатор для каждого const объекта. Эта функция позволяет пользователю помещать const объекты в исходные файлы, которые включены более чем в одну единицу перевода.
Влияние на исходную функцию: изменение семантики четко определенной функции.
Сложность преобразования: семантическое преобразование.
Насколько широко используется: редко.

[basic.start.main]
Изменение: main функция не может вызываться рекурсивно и не может быть его адрес взят.
Обоснование: main функция может потребовать специальных действий.
Влияние на исходный объект: удаление семантически четко определенного объекта.
Сложность конвертации: Тривиально: создайте посредническую функцию, такую ​​как mymain(argc, argv).
Насколько широко используется: редко.

[basic.types]
Изменение: C допускает «совместимые типы» в нескольких местах, а C ++ - нет.
Например, идентичные struct типы с разными именами тегов «совместимы» в C, но являются совершенно разными типами в C ++.
Обоснование: для C ++ необходима более строгая проверка типов.
Влияние на исходный объект: удаление семантически четко определенного объекта.
Сложность преобразования: семантическое преобразование. Механизм «безопасного соединения» обнаружит множество, но не все, таких проблем. Те проблемы, которые не обнаруживаются с помощью безопасного связывания, будут продолжать функционировать должным образом в соответствии с «правилами совместимости компоновки» настоящего международного стандарта.
Насколько широко используется: Обычный.

C.1.3 Clause [conv]: standard conversions [diff.conv]

[conv.ptr]
Изменение: для преобразования void* в тип указателя на объект требуется приведение типов.

char a[10];
void* b=a;
void foo() {
  char* c=b;
}

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

char* c = (char*) b;


Насколько широко используется: это довольно широко используется, но хорошая практика программирования - добавлять приведение при назначении указателя на пустоту для указателя на объект. Некоторые переводчики ISO C выдают предупреждение, если приведение не используется.

C.1.4 Clause [expr]: expressions [diff.expr]

[expr.call]
Изменение: Неявное объявление функций запрещено.
Обоснование: типобезопасная природа C ++.
Влияние на исходный объект: удаление семантически четко определенного объекта. Примечание: исходная функция была помечена как «устаревшая» в ISO C.
Сложность преобразования: синтаксическое преобразование. Средства для создания явных объявлений функций довольно широко распространены на рынке.
Насколько широко используется: Обычный.

[expr.post.incr], Изменение: оператор декремента не может использоваться с операндом. Обоснование: функция с удивительной семантикой. Влияние на исходную функцию: допустимое выражение ISO C, использующее оператор декремента для lvalue (например, через C typedef in ), неправильно сформировано в этом международном стандарте. [expr.pre.incr]
bool

bool <stdbool.h>

[expr.sizeof], Изменение: Типы должны определяться в объявлениях, а не в выражениях. В C выражение sizeof или выражение приведения может определять новый тип. Например, [expr.cast]

p = (void*)(struct x {int i;} *)0;

определяет новый тип struct x.
Обоснование: этот запрет помогает прояснить расположение определений в исходном коде.
Влияние на исходный объект: удаление семантически четко определенного объекта.
Сложность преобразования: синтаксическое преобразование.
Насколько широко используется: редко.

[expr.cond], [expr.ass], Изменение: Результат условного выражения, выражений присваивания или выражений запятой может быть именующим. Обоснование: C ++ - объектно-ориентированный язык, в котором относительно больше внимания уделяется lvalue. Например, функции могут возвращать lvalue. Влияние на исходную функцию: изменение семантики четко определенной функции. Некоторые выражения C, которые неявно полагаются на преобразования lvalue-to-rvalue, дадут разные результаты. Например, [expr.comma]


char arr[100];
sizeof(0, arr)

дает 100 в C ++ и sizeof(char*) C.
Сложность преобразования: программы должны добавлять явное приведение к соответствующему rvalue.
Насколько широко используется: редко.

C.1.5 Clause [stmt.stmt]: statements [diff.stat]

[stmt.switch], Изменение: теперь невозможно пропустить объявление с явным или неявным инициализатором (за исключением всего не введенного блока). Обоснование: Конструкторы, используемые в инициализаторах, могут выделять ресурсы, которые необходимо отменить при выходе из блока. Разрешение перехода за пределы инициализаторов потребует сложного определения распределения во время выполнения. Более того, любое использование неинициализированного объекта может привести к катастрофе. С помощью этого простого правила времени компиляции C ++ гарантирует, что если инициализированная переменная находится в области видимости, то она обязательно была инициализирована. Влияние на исходный объект: удаление семантически четко определенного объекта. Сложность преобразования: семантическое преобразование. Насколько широко используется: редко. [stmt.goto]




[stmt.return]
Изменение: теперь недопустимо возвращать (явно или неявно) из функции, которая, как объявлено, возвращает значение без фактического возврата значения.
Обоснование: вызывающий и вызываемый могут предполагать довольно сложные механизмы возврата для возврата объектов класса. Если некоторые пути потока выполняют возврат без указания какого-либо значения, реализация должна включать в себя гораздо больше сложностей. Кроме того, обещание вернуть значение заданного типа, а затем не возвращать такое значение, всегда считалось сомнительной практикой, допускаемой только потому, что в очень старом C не было различий между функциями void и функциями int.
Влияние на исходный объект: удаление семантически четко определенного объекта.
Сложность преобразования: семантическое преобразование. Добавьте в исходный код соответствующее возвращаемое значение, например ноль.
Насколько широко используется: редко. В течение нескольких лет многие существующие реализации C выдавали предупреждения в этом случае.

C.1.6 Clause [dcl.dcl]: declarations [diff.dcl]

[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.

C.1.7 Clause [dcl.decl]: declarators [diff.decl]

[dcl.fct]
Изменение: в C ++ функция, объявленная с пустым списком параметров, не принимает аргументов. В C пустой список параметров означает, что количество и тип аргументов функции неизвестны.

Пример:

int f();            // means   int f(void) in C++
                    // int f( unknown ) in C


Обоснование: Это сделано для того, чтобы избежать ошибочных вызовов функций (т. Е. Вызовов функций с неправильным числом или типом аргументов).
Влияние на исходную функцию: изменение семантики четко определенной функции. Эта функция была отмечена как «устаревшая» в C.
Сложность преобразования: синтаксическое преобразование. Объявления функций, использующие стиль неполного объявления C, должны быть завершены, чтобы стать объявлениями полных прототипов. Программа может нуждаться в дальнейшем обновлении, если разные вызовы одной и той же (не являющейся прототипом) функции имеют разное количество аргументов или если тип соответствующих аргументов различается.
Насколько широко используется: Обычный.

[dcl.fct] [см. [expr.sizeof]]
Изменение: В C ++ типы не могут быть определены в возвращаемых типах или типах параметров. В C эти определения типов разрешены.

Пример:

void f( struct S { int a; } arg ) {}    // valid C, invalid C++
enum E { A, B, C } f() {}               // valid C, invalid C++


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

[dcl.fct.def]
Изменение: В C ++ синтаксис определения функции исключает функцию C «старого стиля». В C синтаксис «старого стиля» разрешен, но считается устаревшим.
Обоснование: прототипы необходимы для обеспечения безопасности типов.
Влияние на исходный объект: удаление семантически четко определенного объекта.
Сложность преобразования: синтаксическое преобразование.
Насколько широко используется: часто встречается в старых программах, но уже известно, что они устарели.

[dcl.init.string]
Изменение: В C ++ при инициализации массива символов строкой количество символов в строке (включая завершающие '\0') не должно превышать количество элементов в массиве. В C массив может быть инициализирован строкой, даже если массив недостаточно велик, чтобы содержать завершающую строку '\0'.

Пример:

char array[4] = "abcd";         // valid C, invalid C++


Обоснование: манипулирование этими незавершенными массивами стандартными строковыми функциями может привести к серьезной катастрофе.
Влияние на исходный объект: удаление семантически четко определенного объекта.
Сложность преобразования: семантическое преобразование. Массивы должны быть объявлены на один элемент больше, чтобы содержать завершающую строку '\0'.
Насколько широко используется: редко. Такой стиль инициализации массива считается плохим стилем кодирования.

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 самом деле означает.
Влияние на исходный объект: удаление семантически четко определенного объекта.
Сложность преобразования: семантическое преобразование. Необходимо переименовать тип или член структуры.
Насколько широко используется: редко.

C.1.9 Clause [special]: special member functions [diff.special]

[class.copy]
Изменение: Копирование летучих объектов.

Неявно объявленный конструктор копии и неявно объявленный оператор присваивания копии не могут сделать копию изменчивого lvalue. Например, в ISO C действует следующее:

struct X { int i; };
volatile struct X x1 = {0};
struct X x2 = x1;               // invalid C++
struct X x3;
x3 = x1;                        // also invalid C++


Обоснование: Подробно обсуждалось несколько альтернатив. Изменение параметра на volatile const X& значительно усложнит создание эффективного кода для объектов класса. Обсуждение предоставления двух альтернативных сигнатур для этих неявно определенных операций вызвало безответные опасения по поводу создания двусмысленностей и усложнения правил, определяющих формирование этих операторов в соответствии с базами и членами.
Влияние на исходный объект: удаление семантически четко определенного объекта.
Сложность преобразования: семантическое преобразование. Если для копии требуется изменчивая семантика, необходимо предоставить конструктор или присваивание, объявленный пользователем. Если требуется энергонезависимая семантика,const_­cast можно использовать явную .
Насколько широко используется: редко.

C.1.10 Clause [cpp]: preprocessing directives [diff.cpp]

[cpp.predefined]
Изменение: __STDC__ определено ли, и если да, то каково его значение, определяется реализацией.
Обоснование: C ++ не идентичен ISO C. Обязательное __STDC__ определение потребует от переводчиков неверных утверждений. Каждая реализация должна выбрать поведение, которое будет наиболее полезным для ее рынка.
Влияние на исходную функцию: изменение семантики четко определенной функции.
Сложность преобразования: семантическое преобразование.
Насколько широко используется. Ссылки на программы и заголовки __STDC__ встречаются довольно часто.

C.2 C++ and ISO C++ 2003 [diff.cpp03]

В этом подпункте перечислены различия между C ++ и ISO C ++ 2003 (ISO / IEC 14882: 2003, Programming Languages — C++) по главам этого документа.

C.2.1 Clause [lex]: lexical conventions [diff.cpp03.lex]

[lex.pptoken]
Изменение: новые виды строковых литералов.
Обоснование: требуется для новых функций.
Влияние на исходную функцию: действительный код C ++ 2003 может не компилироваться или давать другие результаты в соответствии с этим международным стандартом. В частности, макросы по имени R, u8, u8R, u, uR, U, UR, или LR не будут расширены , когда рядом с строковым литералом , но будет интерпретироваться как часть строки литерала. Например,

#define u8 "abc"
const char* s = u8"def";        // Previously "abcdef", now "def"

[lex.pptoken]
Изменение: поддержка определяемых пользователем буквальных строк.
Обоснование: требуется для новых функций.
Влияние на исходную функцию: действительный код C ++ 2003 может не скомпилировать или привести к другим результатам в соответствии с этим международным стандартом, как показано в следующем примере.

#define _x "there"
"hello"_x         // #1

Раньше # 1 состоял бы из двух отдельных токенов предварительной обработки, и макрос _­x был бы расширен. В этом международном стандарте № 1 состоит из одного токена предварительной обработки, поэтому макрос не раскрывается.

[lex.key]
Изменение: новые ключевые слова.
Обоснование: требуется для новых функций.
Влияние на оригинальной функции: Добавлена в таблице 5, следующие идентификаторы новых ключевых слов: alignas, alignof, char16_­t, char32_­t, constexpr, decltype, noexcept, nullptr, static_­assert, и thread_­local. Допустимый код C ++ 2003, использующий эти идентификаторы, недопустим в этом международном стандарте.

[lex.icon]
Изменение: Тип целочисленных литералов.
Обоснование: совместимость с C99.
Влияние на исходную функцию: некоторые целочисленные литералы, размер которых больше, чем может быть представлен, long могут измениться с целочисленного типа без знака на signed long long.

C.2.2 Clause [conv]: standard conversions [diff.cpp03.conv]

[conv.ptr]
Изменение: целочисленными константами нулевого указателя являются только литералы.
Обоснование: устранение неожиданных взаимодействий с шаблонами и постоянными выражениями.
Влияние на исходную функцию: действительный код C ++ 2003 может не скомпилировать или дать другие результаты в соответствии с этим международным стандартом, как показано в следующем примере:

void f(void *);  // #1
void f(...);     // #2
template<int N> void g() {
  f(0*N);        // calls #2; used to call #1
}

C.2.3 Clause [expr]: expressions [diff.cpp03.expr]

[expr.mul]
Изменение: укажите округление для результатов целых чисел / и %.
Обоснование: Повышение переносимости, совместимость с C99.
Влияние на исходную функцию: действительный код C ++ 2003, в котором используется целочисленное деление, округляет результат до 0 или до отрицательной бесконечности, тогда как этот международный стандарт всегда округляет результат до 0.

[expr.log.and]
Изменение: && действительно в type-name.
Обоснование: требуется для новых функций.
Влияние на исходную функцию: действительный код C ++ 2003 может не скомпилировать или дать другие результаты в соответствии с этим международным стандартом, как показано в следующем примере:

bool b1 = new int && false;           // previously false, now ill-formed
struct S { operator int(); };
bool b2 = &S::operator int && false;  // previously false, now ill-formed

C.2.4 Clause [dcl.dcl]: declarations [diff.cpp03.dcl.dcl]

[dcl.spec]
Изменение: удалить auto как спецификатор класса хранения.
Обоснование: Новая функция.
Влияние на исходную функцию: действительный код C ++ 2003, в котором ключевое слово используется в auto качестве спецификатора класса хранения, может быть недопустимым в этом международном стандарте. В этом международном стандарте auto указывает, что тип переменной должен быть выведен из выражения ее инициализатора.

C.2.5 Clause [dcl.decl]: declarators [diff.cpp03.dcl.decl]

[dcl.init.list]
Изменение: сужение ограничений в агрегатных инициализаторах.
Обоснование: ловит ошибки.
Влияние на исходную функцию: действительный код C ++ 2003 может не соответствовать этому международному стандарту. Например, следующий код действителен в C ++ 2003 , но недействителен в настоящем стандарте , потому что double в int этот сужающее преобразование:

int x[] = { 2.0 };

C.2.6 Clause [special]: special member functions [diff.cpp03.special]

[class.ctor], [class.dtor], Изменить: Косвенно-объявленные специальные функции - члены определяются как удаленные , когда неявное определение было бы плохо сформированным. Обоснование: Улучшает ошибку вывода аргументов шаблона. Влияние на исходную функцию: допустимая программа C ++ 2003, использующая одну из этих специальных функций-членов в контексте, где определение не требуется (например, в выражении, которое потенциально не оценивается), становится некорректной. [class.copy]


[class.dtor] (деструкторы)
Изменение: объявленные пользователем деструкторы имеют неявную спецификацию исключения.
Обоснование: Уточнение требований к деструктору.
Влияние на исходную функцию: действующий код C ++ 2003 в этом международном стандарте может выполняться иначе. В частности, деструкторы, которые генерируют исключения, будут вызывать std​::​terminate (без вызова std​::​unexpected), если их спецификация исключения не выбрасывает.

C.2.7 Clause [temp]: templates [diff.cpp03.temp]

[temp.param]
Изменить: Удалить export.
Обоснование: Нет консенсуса по реализации.
Влияние на исходную функцию: действительное объявление C ++ 2003, содержащееся export в этом международном стандарте, неправильно сформировано.

[temp.arg]
Изменение: убраны требования к пробелам для прямоугольных скобок вложенного закрывающего шаблона.
Обоснование: считается постоянным, но незначительным раздражением. Псевдонимы шаблонов, представляющие типы, не относящиеся к классам, усугубят проблемы с пробелами.
Влияние на исходную функцию: изменение семантики четко определенного выражения. Допустимое выражение C ++ 2003, содержащее правую угловую скобку («>»), за которой сразу следует другая правая угловая скобка, теперь можно рассматривать как закрывающие два шаблона. Например, следующий код действителен в C ++ 2003, потому что «>>» является оператором сдвига вправо, но недопустим в этом международном стандарте, поскольку «>>» закрывает два шаблона.

template <class T> struct X { };
template <int N> struct Y { };
X< Y< 1 >> 2 > > x;

[temp.dep.candidate]
Изменение: разрешить зависимые вызовы функций с внутренней связью.
Обоснование: чрезмерно ограничены, упрощают правила разрешения перегрузки.
Влияние на исходную функцию: действующая программа на C ++ 2003 может получить результат, отличный от этого международного стандарта.

C.2.8 Clause [library]: library introduction [diff.cpp03.library]

[library] - Изменение: новые зарезервированные идентификаторы. Обоснование: требуется новыми функциями. Влияние на исходную функцию: действительный код C ++ 2003, который использует любые идентификаторы, добавленные в стандартную библиотеку C ++ этим международным стандартом, может не скомпилировать или дать другие результаты в этом международном стандарте. Полный список идентификаторов, используемых стандартной библиотекой C ++, можно найти в Указателе имен библиотек в этом международном стандарте. [thread]


[headers]
Изменение: новые заголовки.
Обоснование: новая функциональность.
Влияние на исходной функции: Следующие C ++ заголовки являются новыми: <array>, <atomic>, <chrono>, <codecvt>, <condition_­variable>, <forward_­list>, <future>, <initializer_­list>, <mutex>, <random>, <ratio>, <regex>, <scoped_­allocator>, <system_­error>, <thread>, <tuple>, <typeindex>, <type_­traits>,
<unordered_­map>, и <unordered_­set>. Кроме того, следующие заголовки совместимости С являются новыми: <ccomplex>, <cfenv>, <cinttypes>, <cstdalign>, <cstdbool>, <cstdint>, <ctgmath>, и <cuchar>. Допустимый код C ++ 2003, в котором #includeзаголовки с такими именами могут быть недопустимыми в этом международном стандарте.

[swappable.requirements]
Влияние на исходную функцию: функция swap перемещена в другой заголовок.
Обоснование: удалить зависимость от <algorithm> for swap.
Влияние на исходную функцию: действительный код C ++ 2003, который был скомпилирован с ожиданием<algorithm> наличия подкачки, возможно, придется вместо этого включить <utility>.

[namespace.posix]
Изменение: Новое зарезервированное пространство имен.
Обоснование: новая функциональность.
Влияние на исходную функцию: глобальное пространство имен posix теперь зарезервировано для стандартизации. Допустимый код C ++ 2003, использующий пространство имен верхнего уровня, posix может быть недопустимым в этом международном стандарте.

[res.on.macro.definitions]
Изменение: Дополнительные ограничения на имена макросов.
Обоснование: Избегайте сложных для диагностики или непереносимых конструкций.
Влияние на исходную функцию: Имена идентификаторов атрибутов не могут использоваться в качестве имен макросов. Действительный C ++ 2003 код , который определяет override, final, carries_­dependencyили в noreturn виде макросов является недействительным в настоящем стандарте.

C.2.9 Clause [language.support]: language support library [diff.cpp03.language.support]

[new.delete.single]
Изменение: Связывание new и delete операторы.
Обоснование: две метательные сигнатуры одного объекта operator new и operator delete теперь определены для формирования базовой функциональности для других операторов. Это поясняет, что замена только этих двух подписей изменяет другие, даже если они не были изменены явно.
Влияние на исходную функцию: действительный код C ++ 2003, заменяющий глобальные операторы new или, deleteможет выполняться иначе в этом международном стандарте. Например, следующая программа должна писать "custom deallocation" дважды: один раз для удаления одного объекта и один раз для удаления массива.

#include <cstdio>
#include <cstdlib>
#include <new>

void* operator new(std::size_t size) throw(std::bad_alloc) {
  return std::malloc(size);
}

void operator delete(void* ptr) throw() {
  std::puts("custom deallocation");
  std::free(ptr);
}

int main() {
  int* i = new int;
  delete i;                     // single-object delete
  int* a = new int[3];
  delete [] a;                  // array delete
}

[new.delete.single]
Изменение: operator new может вызывать исключения, отличные от std​::​bad_­alloc.
Обоснование: последовательное применение noexcept.
Влияние на исходную функцию: действительный код C ++ 2003, который предполагает, что operator new только глобальные выбросы std​::​bad_­alloc могут выполняться иначе в этом международном стандарте.

C.2.10 Clause [diagnostics]: diagnostics library [diff.cpp03.diagnostics]

[errno]
Изменение: номера локальных ошибок потока.
Обоснование: Поддержка новых возможностей потоков.
Влияние на исходную функцию: действительный, но зависящий от реализации код C ++ 2003, который полагается на errno то, что он одинаков во всех потоках, может изменить поведение в этом международном стандарте.

C.2.11 Clause [utilities]: general utilities library [diff.cpp03.utilities]

[util.dynamic.safety]
Изменение: минимальная поддержка регионов со сборкой мусора.
Обоснование: требуется новой функцией.
Влияние на исходную функцию: действительный код C ++ 2003, скомпилированный без поддержки отслеживаемых указателей, который взаимодействует с новым кодом C ++ с использованием областей, объявленных достижимыми, может иметь другое поведение во время выполнения.

[refwrap], [arithmetic.operations], [comparisons], [logical.operations], [bitwise.operations], Изменение: Стандартные типы объектов функции больше не происходят от или . Обоснование: заменено новой функцией; и больше не определены. Влияние на исходную функцию: действительный код C ++ 2003, который зависит от типов функциональных объектов, производных от этого международного стандарта, или может не компилироваться в соответствии с ним. [depr.negators]
std​::​unary_­function std​::​binary_­function
unary_­function binary_­function
unary_­function binary_­function

C.2.12 Clause [strings]: strings library [diff.cpp03.strings]

[string.classes]
Изменение: basic_­string требования больше не допускают использование строк с подсчетом ссылок.
Обоснование: недействительность немного отличается от строк со счетчиком ссылок. Это изменение упорядочивает поведение данного международного стандарта.
Влияние на исходную функцию: действующий код C ++ 2003 в этом международном стандарте может выполняться иначе.

[string.require]
Изменение: ослабить basic_­string правила признания недействительными.
Обоснование: разрешить оптимизацию с использованием небольших строк.
Влияние на исходную функцию: действующий код C ++ 2003 в этом международном стандарте может выполняться иначе. Некоторые const функции-члены, такие как data и c_­str, больше не делают итераторы недействительными.

C.2.13 Clause [containers]: containers library [diff.cpp03.containers]

[container.requirements]
Изменение: сложность size() функций-членов теперь постоянна.
Обоснование: Отсутствие спецификации сложности size() привело к различным реализациям с несовместимыми характеристиками производительности.
Влияние на исходную функцию: некоторые реализации контейнеров, соответствующие C ++ 2003, могут не соответствовать указанным size() требованиям в этом международном стандарте. Регулировка контейнеров, например, в std​::​list соответствии с более строгими требованиями, может потребовать несовместимых изменений.

[container.requirements]
Изменение: Изменение требований: расслабление.
Обоснование: Разъяснение.
Влияние на исходную функцию: допустимый код C ++ 2003, который пытается удовлетворить указанные требования к контейнеру, теперь может быть переопределен. Код, который пытался переносить между контейнерами, возможно, потребуется изменить следующим образом:

  • не все контейнеры предоставляют size(); использовать empty() вместо size() == 0;

  • не все контейнеры пусты после конструкции (array);

  • не все контейнеры имеют постоянную сложность для swap() (array).

[container.requirements]
Изменение: Изменение требований: конструктивно по умолчанию.
Обоснование: Уточнение требований к контейнерам.
Влияние на исходную функцию: действительный код C ++ 2003, который пытается явно создать экземпляр контейнера с использованием определяемого пользователем типа без конструктора по умолчанию, может не компилироваться.

[sequence.reqmts], Изменение: Изменения подписи: из возвращаемых типов. Обоснование: старая подпись отбрасывала полезную информацию, пересчет которой может быть дорогостоящим. Влияние на исходную функцию: были изменены следующие функции-члены: [associative.reqmts]
void

  • erase(iter) для set, multiset, map, multimap

  • erase(begin, end) для set, multiset, map, multimap

  • insert(pos, num, val) для vector, deque, list, forward_­list

  • insert(pos, beg, end) для vector, deque, list, forward_­list

Допустимый код C ++ 2003, который полагается на возвращение этих функций void (например, код, который создает указатель на функцию-член, указывающую на одну из этих функций), не сможет скомпилировать с этим международным стандартом.

[sequence.reqmts], Изменение: подпись меняется: с на параметры. Обоснование: превышение спецификации. Влияние на исходную функцию: подписи следующих функций-членов изменились с принятия на принятие : [associative.reqmts]
iterator const_­iterator

iterator const_­iterator

  • insert(iter, val) для vector, deque, list, set, multiset, map, multimap

  • insert(pos, beg, end) для vector, deque, list, forward_­list

  • erase(begin, end) для set, multiset, map, multimap

  • все формы list​::​splice

  • все формы list​::​merge

Допустимый код C ++ 2003, использующий эти функции, может не соответствовать этому международному стандарту.

[sequence.reqmts], Изменение: Подпись изменения: . Обоснование: производительность, совместимость с семантикой перемещения. Влияние на исходный объект: для , и переданное значение заливки теперь передается по ссылке, а не по значению, и была добавлена ​​дополнительная перегрузка . Допустимый код C ++ 2003, использующий эту функцию, может не соответствовать этому международному стандарту. [associative.reqmts]
resize

vector deque list resize resize

C.2.14 Clause [algorithms]: algorithms library [diff.cpp03.algorithms]

[algorithms.general]
Изменение: состояние результата входов после применения некоторых алгоритмов.
Обоснование: требуется новой функцией.
Влияние на исходную функцию: действующая программа C ++ 2003 может обнаружить, что объект с допустимым, но неуказанным состоянием имеет другое действительное, но неуказанное состояние в соответствии с настоящим международным стандартом. Например, std​::​remove и std​::​remove_­if может оставить хвост входной последовательности с другим набором значений, чем раньше.

C.2.15 Clause [numerics]: numerics library [diff.cpp03.numerics]

[complex.numbers]
Изменение: указанное представление комплексных чисел.
Обоснование: совместимость с C99.
Влияние на исходную функцию: действительный код C ++ 2003, в котором используются зависящие от реализации знания о двоичном представлении требуемых специализаций шаблонов, std​::​complex может быть несовместим с этим международным стандартом.

C.2.16 Clause [input.output]: input/output library [diff.cpp03.input.output]

[istream::sentry], [ostream::sentry], Изменение: Укажите использование в существующем логические функции преобразования. Обоснование: прояснить намерения, избегать обходных путей. Влияние на исходную функцию: действительный код C ++ 2003, основанный на неявных логических преобразованиях, не будет компилироваться с этим международным стандартом. Такие преобразования происходят в следующих условиях:[iostate.flags]
explicit

  • передача значения функции, которая принимает аргумент типа bool;

  • использование operator== для сравнения с false или true;

  • возврат значения из функции с типом возврата bool;

  • инициализация членов типа bool через агрегатную инициализацию;

  • инициализация, const bool& которая привязывается к временному.

[ios::failure]
Изменение: изменить базовый класс std​::​ios_­base​::​failure.
Обоснование: более подробные сообщения об ошибках.
Влияние на исходный элемент: std​::​ios_­base​::​failure больше не является производным от std​::​exception, а является производным от std​::​system_­error, который, в свою очередь, является производным от std​::​runtime_­error. Допустимый код C ++ 2003, предполагающий, что он std​::​ios_­base​::​failure является производным напрямую, std​::​exception в этом международном стандарте может выполняться иначе.

[ios.base]
Изменение: типы флагов в std​::​ios_­base теперь являются битовыми масками со значениями, определенными как статические члены constexpr.
Обоснование: требуется для новых функций.
Влияние на исходную функцию: действительный код C ++ 2003, который полагается на std​::​ios_­base типы флагов, представленные std​::​bitset как целочисленный тип или как целочисленный, может не скомпилировать с этим международным стандартом. Например:

#include <iostream>

int main() {
  int flag = std::ios_base::hex;
  std::cout.setf(flag);         // error: setf does not take argument of type int
}

C.3 C++ and ISO C++ 2011 [diff.cpp11]

В этом подпункте перечислены различия между C ++ и ISO C ++ 2011 (ISO / IEC 14882: 2011, Programming Languages — C++) по главам этого документа.

C.3.1 Clause [lex]: lexical conventions [diff.cpp11.lex]

[lex.ppnumber]
Изменение: pp-number может содержать одну или несколько одинарных кавычек.
Обоснование: необходимо включить одинарные кавычки в качестве разделителей цифр.
Влияние на исходную функцию: действительный код C ++ 2011 может не компилироваться или может изменить значение в этом международном стандарте. Например, следующий код действителен как в C ++ 2011, так и в этом международном стандарте, но вызов макроса дает разные результаты, потому что одинарные кавычки разделяют символьный литерал в C ++ 2011, тогда как в этом международном стандарте они являются разделителями цифр:

#define M(x, ...) __VA_ARGS__
int x[2] = { M(1'2,3'4, 5) };
// int x[2] = { 5 };      — C++ 2011
// int x[2] = { 3'4, 5 }; — this International Standard

C.3.2 Clause [basic]: basic concepts [diff.cpp11.basic]

[basic.stc.dynamic.deallocation]
Изменение: Новый обычный (не-размещаемый) деаллокатор.
Обоснование: требуется для освобождения размера.
Влияние на исходную функцию: действующий код C ++ 2011 может объявлять функцию глобального размещения и функцию освобождения следующим образом:

void* operator new(std::size_t, std::size_t);
void operator delete(void*, std::size_t) noexcept;

Однако в этом международном стандарте объявление of operator delete может соответствовать предопределенному обычному (без размещения) operator delete ([basic.stc.dynamic]). Если это так, программа плохо сформирована, как это было для функций распределения членов класса и функций освобождения ([expr.new]).

C.3.3 Clause [expr]: expressions [diff.cpp11.expr]

[expr.cond]
Изменение: условное выражение с выражением throw в качестве второго или третьего операнда сохраняет тип и категорию значения другого операнда.
Обоснование: Ранее санкционированные преобразования (lvalue-to-rvalue, array-to-pointerи function-to-pointer стандартные преобразования), особенно создание временного вследствие Lvalue к Rvalue преобразования, было рассмотрены безвозмездным и удивительно.
Влияние на исходную функцию: действительный код C ++ 2011, который полагается на преобразования, может вести себя по-другому в этом международном стандарте:

struct S {
  int x = 1;
  void mf() { x = 2; }
};
int f(bool cond) {
  S s;
  (cond ? s : throw 0).mf();
  return s.x;
}

В C ++ 2011 f(true) возвращает 1. В этом международном стандарте он возвращается 2.

sizeof(true ? "" : throw 0)

В C ++ 2011 выражение дает sizeof(const char*). В этом международном стандарте он уступает sizeof(const char[1]).

C.3.4 Clause [dcl.dcl]: declarations [diff.cpp11.dcl.dcl]

[dcl.constexpr]
Изменение: constexpr нестатические функции-члены не являются неявно const функциями-членами.
Обоснование: необходимо, чтобы constexpr функции-члены могли изменять объект.
Влияние на исходную функцию: действительный код C ++ 2011 может не соответствовать этому международному стандарту. Например, следующий код действителен в C ++ 2011, но недействителен в этом международном стандарте, поскольку он дважды объявляет одну и ту же функцию-член с разными типами возврата:

struct S {
  constexpr const int &f();
  int &f();
};

C.3.5 Clause [dcl.decl]: declarators [diff.cpp11.dcl.decl]

[dcl.init.aggr]
Изменение: классы с инициализаторами членов по умолчанию могут быть агрегатами.
Обоснование: необходимо разрешить использование инициализаторов членов по умолчанию при агрегированной инициализации.
Влияние на исходную функцию: действительный код C ++ 2011 может не компилироваться или может изменить значение в этом международном стандарте.

struct S { // Aggregate in C++ 2014 onwards.
  int m = 1;
};
struct X {
  operator int();
  operator S();
};
X a{};
S b{a};  // uses copy constructor in C++ 2011,
         // performs aggregate initialization in this International Standard

C.3.6 Clause [library]: library introduction [diff.cpp11.library]

[headers]
Изменение: новый заголовок.
Обоснование: новая функциональность.
Влияние на исходную функцию: <shared_­mutex> новый заголовок C ++ . Допустимый код C ++ 2011, который #includeявляется заголовком с таким именем, может быть недопустимым в этом международном стандарте.

C.3.7 Clause [input.output]: input/output library [diff.cpp11.input.output]

[c.files]
Изменение: gets не определено.
Обоснование: использование gets считается опасным.
Влияние на исходную функцию: действительный код C ++ 2011, использующий эту gets функцию, может не соответствовать этому международному стандарту.

C.4 C++ and ISO C++ 2014 [diff.cpp14]

В этом подпункте перечислены различия между C ++ и ISO C ++ 2014 (ISO / IEC 14882: 2014, Programming Languages — C++) по главам этого документа.

C.4.1 Clause [lex]: lexical conventions [diff.cpp14.lex]

[lex.phases]
Изменение: Удаление поддержки триграфа как обязательной функции.
Обоснование: предотвращает случайное использование триграфов в необработанных строковых литералах и комментариях.
Влияние на исходную функцию: действительный код C ++ 2014, в котором используются триграфы, может быть недействительным или может иметь другую семантику в этом международном стандарте. Реализации могут выбрать перевод триграфов, как указано в C ++ 2014, если они появляются за пределами необработанного строкового литерала, как часть определяемого реализацией сопоставления символов физического исходного файла с базовым исходным набором символов.

[lex.ppnumber]
Изменение: pp-number может содержать и . Обоснование: необходимо включить шестнадцатеричные плавающие литералы. Влияние на исходную функцию: действительный код C ++ 2014 может не компилироваться или давать другие результаты в соответствии с этим международным стандартом. В частности, последовательности символов, такие как и, представляют собой три отдельных токена каждая в C ++ 2014, но один единственный токен в этом международном стандарте. p signP sign

0p+0 0e1_­p+0

#define F(a) b ## a
int b0p = F(0p+0);  // ill-formed; equivalent to “int b0p = b0p + 0;” in C++ 2014

C.4.2 Clause [expr]: expressions [diff.cpp14.expr]

[expr.post.incr], Изменение: удалить оператор приращения с операндом. Обоснование: устаревшая функция с иногда неожиданной семантикой. Влияние на исходную функцию: допустимое выражение C ++ 2014, использующее оператор приращения для lvalue, неправильно сформировано в этом международном стандарте. Обратите внимание, что это может произойти, если lvalue имеет тип, заданный параметром шаблона. [expr.pre.incr]
bool

bool

[expr.new], Изменение: Механизм динамического выделения для чрезмерно выровненных типов. Обоснование: упростить использование чрезмерно выровненных типов. Влияние на исходную функцию: в C ++ 2014 код, который использует a для выделения объекта с чрезмерно выровненным типом класса, где этот класс не имеет собственных функций распределения, используется для выделения памяти. В этом международном стандарте вместо него используется. [expr.delete]


new-expression​::​operator new(std​::​size_­t)​::​operator new(std​::​size_­t, std​::​align_­val_­t)

C.4.3 Clause [dcl.dcl]: declarations [diff.cpp14.dcl.dcl]

[dcl.stc]
Изменение: удаление . Обоснование: разрешить повторное использование устаревшего ключевого слова в будущих версиях этого международного стандарта. Влияние на исходную функцию: действительное объявление C ++ 2014, в котором используется символ, неверно сформулировано в этом международном стандарте. Спецификатор можно просто удалить, чтобы сохранить исходное значение. register storage-class-specifier

register storage-class-specifier

[dcl.spec.auto]
Изменение: auto вычет из braced-init-list.
Обоснование: более интуитивное поведение дедукции.
Влияние на исходную функцию: действительный код C ++ 2014 может не компилироваться или может изменить значение в этом международном стандарте. Например:

auto x1{1};    // was std​::​initializer_­list<int>, now int
auto x2{1, 2}; // was std​::​initializer_­list<int>, now ill-formed

C.4.4 Clause [dcl.decl]: declarators [diff.cpp14.decl]

[dcl.fct]
Изменение: сделайте спецификации исключений частью системы типов.
Обоснование: повышение безопасности типов.
Влияние на исходную функцию: действительный код C ++ 2014 может не скомпилировать или изменить значение в этом международном стандарте:

void g1() noexcept;
void g2();
template<class T> int f(T *, T *);
int x = f(g1, g2);    // ill-formed; previously well-formed

[dcl.init.aggr]
Изменение: определение агрегата расширено для применения к определяемым пользователем типам с базовыми классами.
Обоснование: для повышения удобства инициализации агрегата.
Влияние на исходную функцию: действительный код C ++ 2014 может не компилироваться или давать другие результаты в соответствии с настоящим международным стандартом; инициализация из пустого списка инициализаторов будет выполнять агрегатную инициализацию вместо вызова конструктора по умолчанию для затронутых типов:

struct derived;
struct base {
  friend struct derived;
private:
  base();
};
struct derived : base {};

derived d1{};       // Error. The code was well-formed before.
derived d2;         // still OK

C.4.5 Clause [special]: special member functions [diff.cpp14.special]

[class.inhctor.init]
Изменение: при наследовании конструктора конструктор больше не внедряется в производный класс.
Обоснование: лучшее взаимодействие с другими языковыми функциями.
Влияние на исходную функцию: действительный код C ++ 2014, в котором используются наследующие конструкторы, может быть недействительным или иметь другую семантику. A, using-declaration который называет конструктор, теперь делает соответствующие конструкторы базового класса видимыми для инициализации производного класса, а не объявляет дополнительные конструкторы производного класса.

struct A {
  template<typename T> A(T, typename T::type = 0);
  A(int);
};
struct B : A {
  using A::A;
  B(int);
};
B b(42L); // now calls B(int), used to call B<long>(long),
          // which called A(int) due to substitution failure
          // in A<long>(long).

C.4.6 Clause [temp]: templates [diff.cpp14.temp]

[temp.deduct.type]
Изменение: возможность выводить из типа аргумента шаблона, не являющегося типом.
Обоснование: в сочетании с возможностью объявлять аргументы шаблона, не являющиеся типом, с типами-заполнителями, позволяет частичным специализациям разлагаться на основе типа, выведенного для аргумента шаблона, не являющегося типом.
Влияние на исходную функцию: действительный код C ++ 2014 может не компилироваться или давать другие результаты в соответствии с этим международным стандартом:

template <int N> struct A;
template <typename T, T N> int foo(A<N> *) = delete;
void foo(void *);
void bar(A<0> *p) {
  foo(p); // ill-formed; previously well-formed
}

C.4.7 Clause [except]: exception handling [diff.cpp14.except]

[except.spec]
Изменение: удалить спецификации динамических исключений.
Обоснование: спецификации динамических исключений были устаревшей функцией, которая была сложной и неустойчивой в использовании. Они плохо взаимодействовали с системой типов, что стало более серьезной проблемой в этом международном стандарте, где (нединамические) спецификации исключений являются частью типа функции.
Влияние на исходную функцию: действительное объявление функции C ++ 2014, объявление функции-члена, объявление указателя функции или объявление ссылки на функцию, если оно имеет потенциально генерирующую динамическую спецификацию исключения, будет отклонено в этом международном стандарте как некорректно сформированное. Нарушение спецификации динамического исключения без генерации вызовет, terminate а не unexpected может не выполнять раскручивание стека до такого вызова.

C.4.8 Clause [library]: library introduction [diff.cpp14.library]

[namespace.future]
Изменение: новые зарезервированные пространства имен.
Обоснование: Зарезервируйте пространства имен для будущих версий стандартной библиотеки, которые в противном случае могли бы быть несовместимы с существующими программами.
Влияние на исходную функцию: глобальные пространства имен, std за которыми следует произвольная последовательность цифр, зарезервированы для будущей стандартизации. Допустимый код C ++ 2014, который использует такое пространство имен верхнего уровня, например std2, может быть недопустимым в этом международном стандарте.

C.4.9 Clause [utilities]: general utilities library [diff.cpp14.utilities]

[func.wrap]
Изменение: удалены конструкторы, использующие распределители.
Обоснование: Нет консенсуса по реализации.
Влияние на исходную функцию: действительный код C ++ 2014 может не компилироваться или может изменить значение в этом международном стандарте. В частности, построение std​::​function с помощью распределителя плохо сформировано, и конструкция uses-allocator не передает распределитель std​::​function конструкторам в этом международном стандарте.

[util.smartptr.shared]
Изменение: другое ограничение на конверсии из unique_­ptr.
Обоснование: добавление поддержки массивов с shared_­ptrпомощью синтаксиса shared_­ptr<T[]> и shared_­ptr<T[N]>.
Влияние на исходную функцию: действительный код C ++ 2014 может не компилироваться или может изменить значение в этом международном стандарте. Например:

#include <memory>
std::unique_ptr<int[]> arr(new int[1]);
std::shared_ptr<int> ptr(std::move(arr)); // error: int(*)[] is not compatible with int*

C.4.10 Clause [strings]: strings library [diff.cpp14.string]

[basic.string]
Изменение: .data() добавлен неконстантный член.
Обоснование: Отсутствие неконстантного .data() отличия от аналогичного члена std​::​vector. Это изменение упорядочивает поведение данного международного стандарта.
Влияние на исходную функцию: перегруженные функции с разными путями кода char* и const char* аргументами будут выполняться по-разному при вызове с неконстантным строковым .data() членом в этом международном стандарте.

int f(char *) = delete;
int f(const char *);
string s;
int x = f(s.data()); // ill-formed; previously well-formed

C.4.11 Clause [containers]: containers library [diff.cpp14.containers]

[associative.reqmts]
Изменение: Изменение требований:
Обоснование: Повышение переносимости, уточнение требований к ассоциативному контейнеру.
Влияние на исходную функцию: действительный код C ++ 2014, который пытается использовать ассоциативные контейнеры, имеющие объект сравнения с неконстантным оператором вызова функции, может не компилироваться в этом международном стандарте:

#include <set>

struct compare
{
  bool operator()(int a, int b)
  {
    return a < b;
  }
};

int main() {
  const std::set<int, compare> s;
  s.find(0);
}

C.4.12 Annex [depr]: compatibility features [diff.cpp14.depr]


Изменение: Шаблоны классов auto_­ptr, unary_­functionи binary_­function, функциональные шаблоны random_­shuffle, и шаблоны функций (и их возвращаемые типы) ptr_­fun, mem_­fun, mem_­fun_­ref, bind1st, и bind2nd не определены.
Обоснование: заменены новыми функциями.
Влияние на исходную функцию: действительный код C ++ 2014, использующий эти шаблоны классов и шаблоны функций, может не соответствовать этому международному стандарту.


Изменение: удалить старые члены iostreams [depr.ios.members].
Обоснование: Избыточная функция для совместимости с предварительно стандартным кодом отслужила свое время.
Влияние на исходную функцию: действующая программа C ++ 2014, использующая эти идентификаторы, может быть неправильно сформирована в этом международном стандарте.

C.5 C standard library [diff.library]

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

C.5.1 Modifications to headers [diff.mods.to.headers]

Для совместимости со стандартной библиотекой C стандартная библиотека C ++ предоставляет перечисленные в C заголовки [depr.c.headers], но их использование не рекомендуется в C ++.

Там нет C ++ заголовков для заголовков C , и , равно как и заголовки C сама часть C ++.<stdatomic.h><stdnoreturn.h> <threads.h>

Заголовки C ++ ( ) и ( ), а также соответствующие им заголовки C и и не содержат никакого содержимого из стандартной библиотеки C, а вместо этого просто включают другие заголовки из стандартной библиотеки C ++. <ccomplex>[depr.ccomplex.syn] <ctgmath>[depr.ctgmath.syn] <complex.h> <tgmath.h>

Заголовки <ciso646>, <cstdalign> ([depr.cstdalign.syn]) и <cstdbool> ([depr.cstdbool.syn]) не имеют смысла в C ++. Использование С ++ заголовки <ccomplex>, <cstdalign>, <cstdbool>и <ctgmath> является устаревшим ([depr.c.headers]).

C.5.2 Modifications to definitions [diff.mods.to.definitions]

C.5.2.1 Types char16_­t and char32_­t [diff.char16]

Типы char16_­t и char32_­t являются отдельными типами, а не определениями существующих целочисленных типов. Токены char16_­t и char32_­t находятся keywords в настоящем международном стандарте. Они не отображаются как имена макросов, определенные в <cuchar>.

C.5.2.2 Type wchar_­t [diff.wchar.t]

Тип wchar_­t - это отдельный тип, а не определение существующего целочисленного типа. В этом международном стандарте токен wchar_­t является символом a keyword . Это не появляется как имя типа , определенного в любом из , или .<cstddef><cstdlib> <cwchar>

C.5.2.3 Header <assert.h> [diff.header.assert.h]

В этом международном стандарте токен static_­assert является символом a keyword . Он не отображается как имя макроса, определенное в <cassert>.

C.5.2.4 Header <iso646.h> [diff.header.iso646.h]

Маркеры and, and_­eq, bitand, bitor, compl, not_­eq, not, or, or_­eq, xor, и xor_­eq являются keywords в настоящем стандарте. Они не отображаются как имена макросов, определенные в <ciso646>.

C.5.2.5 Header <stdalign.h> [diff.header.stdalign.h]

Маркер alignas - это ключевое слово в этом международном стандарте ([lex.key]). Он не отображается как имя макроса, определенное в ( ). <cstdalign>[depr.cstdalign.syn]

C.5.2.6 Header <stdbool.h> [diff.header.stdbool.h]

Жетоны bool, trueи false указаны keywords в этом международном стандарте. Они не отображаются как имена макросов, определенные в ( ).<cstdbool>[depr.cstdbool.syn]

C.5.2.7 Macro NULL [diff.null]

Макрос NULL, определенный в любом из , , , , , , или , является реализацией определенного C ++ константного указателя NULL в настоящем стандарте ( ).<clocale><cstddef><cstdio><cstdlib><cstring><ctime> <cwchar>[support.types]

C.5.3 Modifications to declarations [diff.mods.to.declarations]

Заголовок : следующие функции имеют разные объявления: <cstring>

В подпункте [cstring.syn] описаны изменения.

Заголовок : следующие функции имеют разные объявления: <cwchar>

В подпункте [cwchar.syn] описаны изменения.

Заголовок объявляет имя в дополнение к именам, объявленным в стандартной библиотеке C. <cstddef> nullptr_­t <stddef.h>

C.5.4 Modifications to behavior [diff.mods.to.behavior]

Заголовок : Следующие функции ведут себя по-разному: <cstdlib>

В подпункте [support.start.term] описаны изменения.

Заголовок : Следующие функции ведут себя по-разному: <csetjmp>

В подпункте [csetjmp.syn] описаны изменения.

C.5.4.1 Macro offsetof(type, member-designator) [diff.offsetof]

Макрос offsetof, определенный в , принимает ограниченный набор аргументов в этом международном стандарте. Подпункт описывает изменение.<cstddef> type [support.types.layout]

C.5.4.2 Memory allocation functions [diff.malloc]

Функции aligned_­alloc, calloc, mallocи realloc ограничены в настоящем стандарте. В подпункте [c.malloc] описаны изменения.