Pergunta

O Artigo da Wikipédia sobre ANSI C diz:

Um dos objetivos do processo de padronização ANSI C era produzir um superconjunto de K&R C (o primeiro padrão publicado), incorporando muitos dos recursos não oficiais introduzidos posteriormente.No entanto, o comitê de padrões também incluiu vários novos recursos, como protótipos de funções (emprestados da linguagem de programação C++) e um pré-processador mais capaz.A sintaxe para declarações de parâmetros também foi alterada para refletir o estilo C++.

Isso me faz pensar que existem diferenças.No entanto, não vi uma comparação entre K&R C e ANSI C.Existe tal documento?Se não, quais são as principais diferenças?

EDITAR:Acredito que o livro K&R diz "ANSI C" na capa.Pelo menos acredito que a versão que tenho em casa sim.Então talvez não haja mais diferença?

Foi útil?

Solução

Pode haver alguma confusão aqui sobre o que é "K&R C".O termo refere -se ao idioma, conforme documentado na primeira edição de "The C Programming Language". A grosso modo:a linguagem de entrada do compilador Bell Labs C por volta de 1978.

Kernighan e Ritchie estiveram envolvidos no processo de padronização ANSI.O dialeto "ANSI C" substituiu "K&R C" e as edições subsequentes de "The C Programming Language" adotam as convenções ANSI."K&R C" é uma "linguagem morta", exceto na medida em que alguns compiladores ainda aceitam código legado.

Outras dicas

Os protótipos de funções foram a mudança mais óbvia entre K&R C e C89, mas houve muitos outros.Muito trabalho importante também foi feito para padronizar a biblioteca C.Embora a biblioteca C padrão fosse uma codificação da prática existente, ela codificou múltiplo práticas existentes, o que tornou tudo mais difícil.PJO livro de Plauger, A biblioteca C padrão, é uma ótima referência e também conta alguns detalhes dos bastidores de por que a biblioteca acabou do jeito que acabou.

O padrão ANSI/ISO C é muito semelhante ao K&R C em muitos aspectos.A intenção era que a maior parte do código C existente fosse construída em compiladores ANSI sem muitas alterações.Crucialmente, porém, na era pré-padrão, a semântica da linguagem estava aberta à interpretação por cada fornecedor de compilador.ANSI C trouxe uma descrição comum da semântica da linguagem que colocou todos os compiladores em pé de igualdade.É fácil considerar isto como garantido agora, cerca de 20 anos depois, mas esta foi uma conquista significativa.

Na maioria das vezes, se você não possui uma base de código C pré-padrão para manter, ficará feliz por não precisar se preocupar com isso.Se você fizer isso - ou pior ainda, se estiver tentando trazer um programa antigo para padrões mais modernos - então você tem minha simpatia.

Existem algumas pequenas diferenças, mas acho que as edições posteriores do K&R são para ANSI C, então não há mais diferença real.
"C Classic", por falta de termos melhores, tinha uma maneira ligeiramente diferente de definir funções, ou seja,

int f( p, q, r )  
int p, float q, double r;  
{  
    // Code goes here  
}

Acredito que a outra diferença foram os protótipos de funções.Os protótipos não precisavam - na verdade, não podiam - receber uma lista de argumentos ou tipos.Em ANSI C eles fazem.

  1. protótipo de função.
  2. qualificadores constantes e voláteis.
  3. amplo suporte de caráter e internacionalização.
  4. permite que o ponteiro de função seja usado sem desreferenciação.

Outra diferença é que os tipos de retorno de função e de parâmetro não precisam ser definidos.Eles seriam considerados ints.

f(x)
{
    return x + 1;
}

e

int f(x)
int x;
{
    return x + 1;
}

são idênticos.

  • PROTOTIPAGEM DE FUNÇÃO:ANSI C adota a técnica de protótipo de função c++ onde a definição e declaração de função incluem nomes de função, argumentos t, tipos de dados e tipos de dados de valor de retorno. O protótipo de função permite que os compiladores ANSI verifiquem a chamada de função no programa do usuário que passa um número inválido de argumento ou tipos de dados de argumento incompatíveis. Estes corrigem uma grande fraqueza dos compiladores K&R C: chamadas inválidas no programa do usuário geralmente passam na compilação, mas fazem com que o programa trave quando são executados

A diferença é:

  1. Protótipo
  2. amplo suporte de caráter e internacionalização
  3. Suporte para palavras-chave const e voláteis
  4. permitir que ponteiros de função sejam usados ​​como desreferenciação

As principais diferenças entre ANSI C e K&R C são as seguintes:

  • prototipagem de função
  • suporte dos qualificadores de tipo de dados const e voláteis
  • apoiar caracteres amplos e internacionalização
  • permitir que ponteiros de função sejam usados ​​sem desreferenciar

ANSI C adota a técnica de protótipo de função c++ onde a definição e declaração de funções incluem nomes de funções, tipos de dados de argumentos e tipos de dados de valor de retorno.O protótipo de função permite que o compilador ANSI C verifique chamadas de função em programas de usuário que passam números inválidos de argumentos ou tipos de dados de argumentos incompatíveis.Isso corrige os principais pontos fracos do compilador K&R C.

Exemplo:to declara uma função foo e requer que foo receba dois argumentos

 unsigned long foo (char* fmt, double data)
 {
      /*body of foo */
 }

A maior diferença, eu acho, é a prototipagem de funções e a sintaxe para descrever os tipos de argumentos de função.

Uma grande diferença que ninguém mencionou ainda é que antes do ANSI, C era definido em grande parte por precedentes e não por especificações;nos casos em que certas operações teriam consequências previsíveis em algumas plataformas, mas não em outras (por exemplo,usando operadores relacionais em dois ponteiros não relacionados), o precedente favorecia fortemente a disponibilização de garantias de plataforma para o programador.Por exemplo:

  1. Em plataformas que definem uma classificação natural entre todos os ponteiros para todos os objetos, pode-se confiar na aplicação dos operadores relacionais a ponteiros arbitrários para produzir essa classificação.

  2. Em plataformas onde o meio natural de testar se um ponteiro é "maior que" outro nunca tem qualquer efeito colateral além de produzir um valor verdadeiro ou falso, a aplicação dos operadores relacionais a ponteiros arbitrários também pode ser confiável para nunca ter nenhum lado -efeitos diferentes de produzir um valor verdadeiro ou falso.

  3. Em plataformas onde dois ou mais tipos inteiros compartilhavam o mesmo tamanho e representação, um ponteiro para qualquer tipo inteiro poderia ser usado para ler ou escrever informações de qualquer outro tipo com a mesma representação.

  4. Em plataformas de complemento de dois, onde estouros de número inteiro são naturalmente agrupados silenciosamente, pode-se confiar que uma operação envolvendo valores não assinados menores que "int" se comportará como se o valor não fosse assinado em casos em que o resultado estaria entre INT_MAX+1u e UINT_MAX e não foi promovido para um tipo maior, nem usado como operando esquerdo de >>, nem qualquer operando de /, %, ou qualquer operador de comparação. Aliás, a justificativa para o Padrão apresenta isso como uma das razões pelas quais pequenos tipos não assinados são promovidos a assinados..

Antes do C89, não estava claro até que ponto os compiladores para plataformas onde as suposições acima não seriam naturalmente válidas poderiam ir para defender essas suposições de qualquer maneira, mas havia poucas dúvidas de que os compiladores para plataformas que poderiam sustentar tais suposições de maneira fácil e barata deveria fazê-lo.Os autores do Padrão C89 não se preocuparam em dizer isso expressamente porque:

  1. Os compiladores cujos escritores não estavam sendo deliberadamente obtusos continuariam fazendo essas coisas quando prático, sem precisar ser informados (a justificativa dada para promover pequenos valores não assinados para assinados reforça fortemente essa visão).

  2. O Padrão apenas exigia que as implementações fossem capazes de executar um programa possivelmente inventado sem estouro de pilha e reconhecia que, embora uma implementação obtusa pudesse tratar qualquer outro programa como invocando Comportamento Indefinido, mas não achava que valia a pena se preocupar com escritores de compiladores obtusos escrevendo implementações que estavam "em conformidade", mas inúteis.

Embora "C89" tenha sido interpretado contemporaneamente como significando "a linguagem definida pelo C89, mais quaisquer recursos e garantias adicionais que a plataforma oferece", os autores do gcc têm promovido uma interpretação que exclui quaisquer recursos e garantias além daqueles exigidos pelo C89.

Apesar de todas as reivindicações ao contary, a K&R era e é perfeitamente capaz de fornecer qualquer tipo de coisa, desde baixo até perto do hardware.O problema agora é encontrar um compilador (de preferência gratuito) que possa fornecer uma compilação limpa em alguns milhões de linhas de K&R C sem ter que mexer com ele. E rodando em algo como um processador AMD multi-core.

Pelo que posso ver, tendo olhado para a fonte da série GCC 4.x.x, não há um hack simples para reativar a funcionalidade de atraso -tradicional e -cpp-tradicional para seu estado de funcionamento anterior sem mais esforço do que estou preparado para coloque em.E é mais simples construir um compilador pré-ansi K&R do zero.

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