Pergunta

Estou acostumado com o antigo C e comecei recentemente a explorar os recursos C99. Eu tenho apenas uma pergunta: meu programa compilará com sucesso se eu usar o C99 no meu programa, a bandeira C99 com gcc e vincular -o às bibliotecas C99 anteriores?

Então, devo manter o velho C89 ou evoluir?

Foi útil?

Solução

Eu acredito que eles são compatíveis nesse aspecto. Isso é o tempo que as coisas que você está compilando não pisar em qualquer um dos novos presentes. Por exemplo, se o código antigo contiver enum bool { false, true }; Então você está com problemas. Como um dinossauro semelhante, estou lentamente abraçando o maravilhoso mundo novo do C99. Afinal, só está por aí à espreita há cerca de 10 anos;)

Outras dicas

Você deve evoluir. Obrigado por ouvir :-)

Na verdade, eu vou expandir isso.

Você está certo que o C99 já existe há um bom tempo. Você deve (na minha opinião) Use esse padrão para qualquer coisa que não seja o código legado (onde você apenas corrige bugs em vez de adicionar novos recursos). Provavelmente não vale a pena para o código legado, mas você deve (como em todas as decisões de negócios) fazer sua própria análise de custo/benefício.

Já estou garantindo que meu novo código seja compatível com o C1X - enquanto ainda não estou usando nenhum dos novos recursos, tento garantir que ele não quebre.

Quanto ao código a ser observado, os autores dos padrões recebem compatibilidade com versões anteriores muito a sério. O trabalho deles nunca era projetar um novo idioma, era codificar as práticas existentes.

A fase em que eles estão no momento lhes permite um pouco mais de latitude na atualização do idioma, mas ainda seguem o juramento hipocrático em termos de sua produção: "Primeiro de tudo, não faça mal".

Geralmente, se o seu código for quebrado com um novo padrão, o compilador será forçado a lhe contar. Portanto, simplesmente compilar sua base de código será um excelente começo. No entanto, se você ler o C99 Racionalidade Documento, você verá a frase "mudança silenciosa" - é isso que você precisa observar.

Essas são mudanças comportamentais no compilador sobre o qual você não precisa ser informado e pode ser a fonte de muita angústia e ranger de dentes se o seu aplicativo começar a agir de forma estranha. Não se preocupe com a "mudança silenciosa em bits C89" - se eles fossem um ProBlerm, você já teria sido mordido por eles.

A propósito, esse documento é uma excelente leitura para entender por que o padrão real diz o que diz.

Respeitosamente: Experimente e descubra. :-)

No entanto, lembre -se de que, mesmo que você precise consertar algumas diferenças de compilação minior, subir provavelmente vale a pena.

Se você não violar os recursos explícitos do C99, um código C90 funcionará Fine C99 FLAG com outras bibliotecas C99 anteriores.

Mas existem algumas bibliotecas baseadas em DOS no C89, que certamente não funcionarão.

C99 é muito flexível, então fique à vontade para migrar :-)

As convenções de chamadas entre as bibliotecas C não mudaram em séculos e, de fato, não tenho certeza se nunca.

Os sistemas operacionais neste momento dependem muito das convenções de chamada C, uma vez que as APIs C tendem a ser a cola entre as peças do sistema operacional.

Então, basicamente, a resposta é "Sim, os binários serão compatíveis com versões anteriores. Não, naturalmente, o código usando recursos C99 não poderá ser compilado posteriormente com um compilador não C99".

Destina -se a ser compatível com versões anteriores. Ele formaliza extensões que muitos fornecedores já implementaram. É possível, talvez até provável, que um programa bem escrito não tenha problemas ao compilar com o C99.

Na minha experiência, recompilar alguns módulos e não outros para economizar tempo ... desperdiça muito tempo. Geralmente, há alguns detalhes facilmente negligenciados que precisam do novo compilador para tornar tudo compatível.

Existem algumas partes do padrão C89 que são escritas ambiguamente e, dependendo de como se interpreta a regra sobre os tipos de ponteiros e os objetos que estão acessando, o padrão pode ser visto como descrevendo um dos dois idiomas muito diferentes-um dos quais é semanticamente muito mais poderoso e, consequentemente, utilizável em uma gama mais ampla de campos, e uma das quais permite mais oportunidades de otimização baseada em compiladores. O padrão C99 "esclareceu" a regra para deixar claro que não faz nenhum esforço para exigir compatibilidade com o idioma anterior, apesar de ser predominantemente favorecido em muitos campos; Também trata como indefinido algumas coisas que foram definidas em C89, mas apenas porque as regras C89 não foram escritas com precisão suficiente para proibi -las (por exemplo, o uso de memcpy para o tipo punindo nos casos em que o destino tem duração da pilha).

Assim, o C99 pode ser compatível com a linguagem que seus autores pensavam ter sido descrito por C89, mas não é compatível com o idioma que foi processado pela maioria dos compiladores C89 ao longo dos anos 90.

Alguns recursos C89 não são válidos C99

Indiscutivelmente, esses recursos existem apenas por razões históricas e não devem ser usadas no código C89 moderno, mas existem.

O rascunho padrão C99 N1256 O parágrafo 5 prefácio compara o C99 a revisões mais antigas e é um bom lugar para começar a procurar essas incompatibilidades, mesmo que tenha muito mais extensões do que restrições.

Tipos implícitos de retorno e variável

Mencionado por Lutz em um comentário, por exemplo, o seguinte é C89 válido:

static i;
f() { return 1; }

Mas não C99, no qual você tem que escrever:

static int i;
int f() { return 1; }

Isso também impede que chama as funções sem protótipos no C99: Os protótipos são necessários para todas as funções em C89, C90 ou C99?

N1256 diz:

Remova implícito int

Retornar sem expressão para função não vazia

C89 válido, inválido C99:

int f() { return; }

Eu acho que no C89 ele retorna um valor definido pela implementação. N1256 diz:

retornar sem expressão não permitida em função que retorne um valor

Divisão inteira com operando negativo

  • C89: Rodadas para uma implementação definida
  • C99: rodadas para 0

Então, se o seu compilador arredondado para -inf, e você confiou nessa implementação que o comportamento definido, seu compilador agora é forçado a quebrar seu código no C99.

https://stackoverflow.com/a/3604984/895245

N1256 diz:

Divisão inteira confiável

Compatibilidade do Windows

Uma grande preocupação prática é poder compilar no Windows, já que a Microsoft não pretende implementar o C99 muito cedo.

Isso é, por exemplo, por que libgit2 Os limites permitiram os recursos C99.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top