O FDIS possui uma seção para incompatibilidades, no apêndice C.2
"C ++ e ISO C ++ 2003".
Resumo, parafraseando o FDIS aqui, para torná-lo (melhor) adequado como uma resposta SO. Adicionei alguns exemplos para ilustrar as diferenças.
Existem algumas incompatibilidades relacionadas à biblioteca nas quais eu não conheço exatamente as implicações, então deixo essas para que outras pessoas elaborem.
Linguagem principal
#define u8 "abc"
const char *s = u8"def"; // Previously "abcdef", now "def"
#define _x "there"
"hello"_x // now a user-defined-string-literal. Previously, expanded _x .
Novas palavras-chave: alignas, alignof, char16_t, char32_t, constexpr, decltype, noexcept, nullptr, static_assert e thread_local
Certos literais inteiros maiores que podem ser representados por long podem mudar de um tipo inteiro sem sinal para long long assinado.
O código C ++ 2003 válido que usa divisão inteira arredonda o resultado para 0 ou para o infinito negativo, enquanto C ++ 0x sempre arredonda o resultado para 0.
(reconhecidamente não é realmente um problema de compatibilidade para a maioria das pessoas).
O código C ++ 2003 válido que usa a palavra-chave auto
como um especificador de classe de armazenamento pode ser inválido no C ++ 0x.
Conversões limitadas causam incompatibilidades com o C ++ 03. Por exemplo, o código a seguir é válido no C ++ 2003, mas inválido neste padrão internacional, porque double to int é uma conversão restritiva:
int x[] = { 2.0 };
As funções-membro especiais declaradas implicitamente são definidas como excluídas quando a definição implícita tiver sido mal formada.
Um programa C ++ 2003 válido que usa uma dessas funções-membro especiais em um contexto em que a definição não é necessária (por exemplo, em uma expressão que não é potencialmente avaliada) fica mal formada.
Exemplo por mim:
struct A { private: A(); };
struct B : A { };
int main() { sizeof B(); /* valid in C++03, invalid in C++0x */ }
Alguns truques de tamanho foram usados por alguns SFINAE e precisam ser alterados agora :)
Os destruidores declarados pelo usuário têm uma especificação de exceção implícita.
Exemplo por mim:
struct A {
~A() { throw "foo"; }
};
int main() { try { A a; } catch(...) { } }
Esse código chama terminate
em C ++ 0x, mas não em C ++ 03. Porque a especificação de exceção implícita A::~A
no C ++ 0x é noexcept(true)
.
Uma declaração válida do C ++ 2003 contendo export
está incorreta no C ++ 0x.
Uma expressão válida do C ++ 2003 contendo >
seguida imediatamente por outra >
agora pode ser tratada como o fechamento de dois modelos.
No C ++ 03, >>
sempre seria o token do operador de turno.
Permite chamadas dependentes de funções com ligação interna.
Exemplo por mim:
static void f(int) { }
void f(long) { }
template<typename T>
void g(T t) { f(t); }
int main() { g(0); }
No C ++ 03, isso chama f(long)
, mas no C ++ 0x, isso chama f(int)
. Deve-se observar que, tanto em C ++ 03 quanto em C ++ 0x, as seguintes chamadas f(B)
(o contexto de instanciação ainda considera apenas declarações de ligação externa).
struct B { };
struct A : B { };
template<typename T>
void g(T t) { f(t); }
static void f(A) { }
void f(B) { }
int main() { A a; g(a); }
A melhor correspondência f(A)
não é obtida, porque não possui ligação externa.
Alterações na biblioteca
O código C ++ 2003 válido que usa qualquer identificador adicionado à biblioteca padrão C ++ de C ++ 0x pode falhar ao compilar ou produzir resultados diferentes neste Padrão Internacional.
O código C ++ 2003 válido que #includes
cabeçalhos com nomes de novos cabeçalhos de biblioteca padrão C ++ 0x pode ser inválido nesta Norma.
O código C ++ 2003 válido que foi compilado esperando que a troca ocorra <algorithm>
talvez precise incluir<utility>
O espaço para nome global posix
agora está reservado para padronização.
Válido código C ++ 2003 que define override
, final
, carries_dependency
, ou noreturn
como macros é inválido em C ++ 0x.
export
palavra - chave? Vou pegar meu casaco.