Eu sei que pelo menos uma das alterações no C ++ 11 que fará com que algum código antigo pare de compilar: a introdução de explicit operator bool()
na biblioteca padrão, substituindo instâncias antigas deoperator void*()
. É verdade que o código que isso quebrará provavelmente é um código que não deveria ter sido válido em primeiro lugar, mas ainda assim é uma mudança de quebra: os programas que costumavam ser válidos não são mais.
Existem outras mudanças de última hora?
export
palavra - chave? Vou pegar meu casaco.mystream.good()
não é o mesmo quebool(mystream)
?good()
é verdadeiro se nenhum sinalizador estiver definido.bool(mystream)
ainda é falso se apenaseofbit
estiver definido.!mystream.fail()
seria o equivalente correto.Respostas:
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
(reconhecidamente não é realmente um problema de compatibilidade para a maioria das pessoas).
Exemplo por mim:
Alguns truques de tamanho foram usados por alguns SFINAE e precisam ser alterados agora :)
Exemplo por mim:
Esse código chama
terminate
em C ++ 0x, mas não em C ++ 03. Porque a especificação de exceção implícitaA::~A
no C ++ 0x énoexcept(true)
.No C ++ 03,
>>
sempre seria o token do operador de turno.Exemplo por mim:
No C ++ 03, isso chama
f(long)
, mas no C ++ 0x, isso chamaf(int)
. Deve-se observar que, tanto em C ++ 03 quanto em C ++ 0x, as seguintes chamadasf(B)
(o contexto de instanciação ainda considera apenas declarações de ligação externa).A melhor correspondência
f(A)
não é obtida, porque não possui ligação externa.Alterações na biblioteca
fonte
export
, acho que os outros TUs não precisariam confiar na instanciação explícita, mas poderiam instanciar o modelo em si. Então , faria diferença se as funções de ligação interna são ou não visíveis no contexto da instanciação.O significado da palavra-chave automática foi alterado.
fonte
auto
palavra - chave, algo está muito errado com seu código. Por que diabos você usaria isso?auto
permanece válido no C ++ 11.int main() { auto int i = 0; return i; }
é C ++ 03 perfeitamente válido, mas um erro de sintaxe no C ++ 11. O único aviso que posso receber dos compiladores no modo C ++ 03 é um aviso sobre compatibilidade.Quebrando a mudança?
Bem, para uma coisa, se você usou
decltype
,constexpr
,nullptr
, etc. como identificadores, então você pode estar em apuros ...fonte
Algumas incompatibilidades principais que não são cobertas pela seção de incompatibilidades:
O C ++ 0x trata o nome da classe injetada como um modelo, se o nome for passado como argumento para um parâmetro do modelo e como um tipo se for passado para um parâmetro do tipo modelo.
O código C ++ 03 válido pode se comportar de maneira diferente se depender do nome da classe injetada para ser sempre um tipo nesses cenários. Código de exemplo retirado do meu clang PR
No C ++ 03, o código chama o segundo nas
g
duas vezes.O C ++ 0x torna alguns nomes que eram dependentes no C ++ 03 agora não-dependentes. E exige que a pesquisa de nome de nomes qualificados não dependentes que se refira aos membros do modelo de classe atual seja repetida na instanciação e exige a verificação de que esses nomes pesquisem da mesma maneira que no contexto de definição de modelo.
O código C ++ 03 válido que depende da regra de dominância agora pode não ser mais compilado devido a essa alteração.
Exemplo:
Esse código C ++ 03 válido que chama
A<int>::f
não é válido em C ++ 0x, porque a pesquisa de nome ao instanciar será encontradaA<int>::f
em oposição aB::f
, causando um conflito com a pesquisa em definição.Neste ponto, não está claro se isso é um defeito no FDIS. O comitê está ciente disso e avaliará a situação.
Uma declaração de uso em que a última parte é igual ao identificador na última parte do qualificador no nome qualificado que denota uma classe base, que usando a declaração agora nomeia o construtor, em vez de membros com esse nome.
Exemplo:
O código de exemplo acima é bem formado em C ++ 03, mas mal formado em C ++ 0x, pois
A::B
ainda é inacessível emmain
.fonte
A falha na extração de fluxo é tratada de maneira diferente.
Exemplo
Alterar proposta
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3246.html#23
Referência padrão
Implementações
O GCC 4.8 gera corretamente para C ++ 11 :
GCC 4.5-4.8 toda a saída para C ++ 03 da seguinte maneira, que parece ser um bug:
O Visual C ++ 2008 Express gera corretamente para C ++ 03:
O Visual C ++ 2012 Express gera incorretamente para o C ++ 11, o que parece ser um problema de status de implementação:
fonte
Como a introdução de operadores de conversão explícita é uma mudança radical? A versão antiga ainda será tão "válida" quanto antes.Sim, a mudança de
operator void*() const
paraexplicit operator bool() const
será uma mudança ininterrupta, mas somente se for usada de uma maneira que esteja errada por si só. O código em conformidade não será quebrado.Agora, outra mudança importante é a proibição de restringir conversões durante a inicialização agregada :
Edit : Apenas lembrete,
std::identity<T>
será removido em C ++ 0x (veja a nota). É uma estrutura de conveniência para tornar os tipos dependentes. Como a estrutura realmente não faz muito, isso deve corrigi-lo:fonte
operator void*
.bool ok = cin >> a; cout << "done reading" << endl; if (ok) { ... }
Não há nada realmente errado com isso no C ++ 03, mas tornou-se um erro no C ++ 11. (Nota: GCC 4.9 ainda temoperator void*() const
aqui, é por isso que não aceita o código em C ++ 11 Modo.)std::identity<T>
não foi removido no C ++ 11, porque não fazia parte do C ++ 03. Existiu brevemente no rascunho para C ++ 11 e foi removido do rascunho antes da padronização.Existem inúmeras alterações na biblioteca de contêineres que permitem códigos mais eficientes, mas interrompem silenciosamente a compatibilidade com versões anteriores para alguns casos de canto.
Considere, por exemplo,
std::vector
construção padrão, C ++ 0x, e alterações de interrupção .fonte
Tem havido muita discussão sobre movimentos implícitos quebrando a compatibilidade com versões anteriores
( uma página antiga com discussão relevante )
Se você ler os comentários, o retorno implícito da movimentação também será uma mudança de última hora.
fonte
C ++ 03: válido.
C ++ 0x:
error: parameter declared 'auto'
fonte
struct x
e sem nome.Características da linguagem
>>
Componentes da biblioteca padrão
Recursos preteridos
fonte