Respostas:
Se você comparar C89
com C++
então aqui estão algumas coisas
int n;
int n; // ill-formed: n already defined
int a[1];
int (*ap)[] = &a; // ill-formed: a does not have type int[]
int b(a) int a; { } // ill-formed: grammar error
struct A { struct B { int a; } b; int c; };
struct B b; // ill-formed: b has incomplete type (*not* A::B)
auto a; // ill-formed: type-specifier missing
C99 adiciona muitos outros casos
// ill-formed: invalid syntax
void f(int p[static 100]) { }
// ill-formed: n is not a constant expression
int n = 1;
int an[n];
// ill-formed: fam has incomplete type
struct A { int a; int fam[]; };
// ill-formed: two names for one parameter?
void copy(int *restrict src, int *restrict dst);
typedef;
é um TU legal em C, mas não em C ++.
auto a;
é válido na revisão padrão C ++ mais recente.
a
?
auto x;
não é válido na revisão mais recente, mas auto x = 0;
é , por exemplo . Fiquei um pouco chocado no início :)
C ++ também tem novas palavras-chave. O seguinte é um código C válido, mas não compilará em C ++:
int class = 1;
int private = 2;
int public = 3;
int virtual = 4;
Existem muitas coisas. Apenas um exemplo simples (deve ser o suficiente para provar que C não é um subconjunto adequado de C ++):
int* test = malloc(100 * sizeof(int));
deve compilar em C, mas não em C ++.
int*
.
void *
, que em C pode ser atribuído a qualquer tipo de ponteiro, e C ++ não pode ser atribuído a nenhum outro tipo de ponteiro.
Em C ++, se você declarar uma struct
, union
ou enum
, seu nome é imediatamente acessível, sem quaisquer qualificadores:
struct foo { ... };
foo x; // declare variable
Em C, isso não funcionará, porque os tipos assim declarados vivem em seus próprios namespaces distintos. Portanto, você deve escrever:
struct foo { ... };
struct foo x; // declare variable
Observe a presença de struct
lá na segunda linha. Você deve fazer o mesmo para union
e enum
(usando suas respectivas palavras-chave), ou use o typedef
truque:
typedef struct { ... } foo;
foo x; // declare variable
Consequentemente, você pode ter vários tipos de tipos diferentes com o mesmo nome em C, uma vez que você pode desambiguar:
struct foo { ... };
typedef enum { ... } foo;
struct foo x;
foo y;
Em C ++, entretanto, embora você possa prefixar um struct
nome com palavra-chave struct
sempre que fizer referência a ele, os namespaces são mesclados e, portanto, o fragmento C acima não é válido. Por outro lado, C ++ especificamente faz uma exceção para permitir que um tipo e um typedef para esse tipo tenham o mesmo nome (obviamente sem efeito), para permitir o uso de typedef
truque inalterado de C.
struct
, union
e enum
) compartilham o mesmo namespace. Um exemplo melhor seriastruct foo { ... }; typedef enum { ... } foo;
Isso também depende da variedade de C que você está usando. Stroustrup tornou o C ++ o mais compatível possível, e não mais compatível, com os padrões ANSI de 1989 e ISO de 1990, e a versão de 1995 não mudou nada. O comitê C foi em uma direção um pouco diferente com o padrão de 1999, e o comitê C ++ mudou o próximo padrão C ++ (provavelmente no próximo ano ou depois) para se conformar com algumas das mudanças.
Stroustrup lista incompatibilidades com C90 / C95 no Apêndice B.2 de "The C ++ Programming Language", Edição Especial (que é a 3ª edição com algum material adicionado):
'a'
é um int
em C, umchar
em C ++.
O tamanho de um enum é int
em C, não necessariamente em C ++.
C ++ tem //
comentários até o fim da linha, C não (embora seja uma extensão comum).
Em C ++, uma struct foo {
definição é foo
inserida no espaço de nomes global, enquanto em C ela teria que ser referida como struct foo
. Isso permite que uma struct
definição sombreie um nome em um escopo externo e tem algumas outras consequências. Além disso, C permite um escopo maior parastruct
definições e as permite em declarações de tipo de retorno e tipo de argumento.
C ++ é mais complicado com os tipos em geral. Ele não permite que um inteiro seja atribuído a um enum
e os void *
objetos não podem ser atribuídos a outros tipos de ponteiro sem uma conversão. Em C, é possível fornecer um inicializador overlarge (char name[5] = "David"
onde C descartará o caractere nulo final).
O C89 permite implícito int
em muitos contextos, e o C ++ não. Isso significa que todas as funções devem ser declaradas em C ++, enquanto em C89 era freqüentemente possível assumir int
tudo o que é aplicável na declaração da função.
Em C, é possível pular de fora de um bloco para dentro usando uma instrução rotulada. Em C ++, isso não é permitido se pular uma inicialização.
C é mais liberal na vinculação externa. Em C, uma const
variável global é implicitamente extern
, e isso não é verdade em C ++. C permite que um objeto de dados global seja declarado várias vezes sem umextern
, mas isso não é verdade em C ++.
Muitas palavras-chave C ++ não são palavras-chave em C, ou são #define
d em cabeçalhos C padrão.
Existem também alguns recursos mais antigos do C que não são mais considerados um bom estilo. Em C, você pode declarar uma função com as definições de argumento após a lista de argumentos. Em C, uma declaração como int foo()
significa que foo()
pode receber qualquer número de qualquer tipo de argumento, enquanto em C ++ é equivalente a int foo(void)
.
Isso parece cobrir tudo, desde Stroustrup.
Se você usar o gcc, pode usar o aviso -Wc++-compat
para dar-lhe avisos sobre o código C que é duvidoso em C ++ de alguma forma. Atualmente é usado no próprio gcc e ficou muito melhor recentemente (talvez tente uma versão noturna para obter o melhor que puder).
(Isso não responde estritamente à pergunta, mas as pessoas podem gostar).
A maior diferença, creio, é que este é um arquivo-fonte C válido:
int main()
{
foo();
}
Observe que eu não declarei foo
lugar nenhum.
Além das diferenças de linguagem, C ++ também faz algumas alterações na biblioteca que herdou de C, por exemplo, algumas funções retornam em const char *
vez de char *
.
s,C,C89,
e observar que é um arquivo de origem C99 inválido.
#include <stdio.h>
int new (int n) {
return n/2;
}
int main(void) {
printf("%d\n", new(10));
return 0;
}
Consulte também a entrada C ++ FAQ .
Várias das respostas aqui cobrem diferenças de sintaxe que fariam com que os compiladores C ++ falhem no código-fonte C89 (ou C99). No entanto, existem algumas diferenças sutis de idioma que são legais em ambos os idiomas, mas que produziriam um comportamento diferente. A sizeof (char)
diferença que Naveen mencionou é um exemplo, mas escrever um programa que irá imprimir "C" se compilado como um programa C (ANSI) e "C ++" se compilado como um programa C ++ lista alguns outros.
Os compiladores C geralmente permitem um pequeno corte que o C ++ não permite. C ++ é muito mais estrito do que C. E geralmente, algumas dessas diferenças dependem do compilador. g ++ permite algumas coisas que o compilador Intel C ++ não permite, por exemplo. Mesmo o código C bem escrito não compilará com um compilador C ++ moderno.
Você não pode comparar idiomas apenas pela sintaxe. Se você fizer isso, talvez possa ver C como um subconjunto de C ++. Na minha opinião, o fato de C ++ ser OO (e C não) é suficiente para dizer que C e C ++ são linguagens diferentes.