Leí en muchos libros que C es un subconjunto de C ++.
Algunos libros dicen que C es un subconjunto de C ++, excepto por los pequeños detalles .
¿Cuáles son algunos casos en los que el código se compilará en C, pero no en C ++?
Si se compara C89
con C++
, aquí hay un par de cosas.
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 agrega muchos otros 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;
es una TU legal en C, pero no en C ++.auto a;
es válido en la revisión estándar más reciente de C ++.a
?auto x;
no es válido en la revisión más reciente, pero por ejemplo loauto x = 0;
es. Al principio estaba un poco sorprendido :)En C,
sizeof('a')
es igual asizeof(int)
.En C ++,
sizeof('a')
es igual asizeof(char)
.fuente
'a'
es unint
. En C ++,'a'
es unchar
.C ++ también tiene nuevas palabras clave. El siguiente es un código C válido, pero no se compilará en C ++:
fuente
Hay muchas cosas. Solo un ejemplo simple (debería ser suficiente para demostrar que C no es un subconjunto adecuado de C ++):
debería compilarse en C pero no en C ++.
fuente
int*
.void *
, que en C se puede asignar a cualquier tipo de puntero, y C ++ no se puede asignar a ningún otro tipo de puntero.En C ++, si declara una
struct
,union
oenum
, su nombre es inmediatamente accesible sin ningún tipo de calificativos:En C, esto no funcionará, porque los tipos así declarados viven en sus propios espacios de nombres distintos. Por tanto, tienes que escribir:
Note la presencia de
struct
allí en la segunda línea. Tienes que hacer lo mismo paraunion
yenum
(usando sus respectivas palabras clave), o usar eltypedef
truco:En consecuencia, puede tener varios tipos de diferentes tipos con el mismo nombre en C, ya que puede eliminar la ambigüedad:
En C ++, sin embargo, aunque puede prefijar un
struct
nombre con una palabra clavestruct
siempre que haga referencia a él, los espacios de nombres se combinan, por lo que el fragmento de C anterior no es válido. Por otro lado, C ++ específicamente hace una excepción para permitir que un tipo y un typedef para ese tipo tengan el mismo nombre (obviamente sin efecto), para permitir el uso detypedef
trucos sin cambios de C.fuente
struct
,union
yenum
) comparten el mismo espacio de nombres. Un mejor ejemplo seríastruct foo { ... }; typedef enum { ... } foo;
Esto también depende de la variedad de C que esté utilizando. Stroustrup hizo C ++ tan compatible como pudo, y no más compatible, con las normas ANSI de 1989 e ISO de 1990, y la versión de 1995 no cambió nada. El comité de C tomó una dirección algo diferente con el estándar de 1999, y el comité de C ++ ha cambiado el siguiente estándar de C ++ (probablemente el próximo año más o menos) para ajustarse a algunos de los cambios.
Stroustrup enumera las incompatibilidades con C90 / C95 en el Apéndice B.2 de "El lenguaje de programación C ++", Edición especial (que es la tercera edición con algo de material agregado):
'a'
es unint
en C, unchar
en C ++.El tamaño de una enumeración está
int
en C, no necesariamente en C ++.C ++ tiene
//
comentarios hasta el final de la línea, C no (aunque es una extensión común).En C ++, una
struct foo {
definición se colocafoo
en el espacio de nombres global, mientras que en C tendría que denominarsestruct foo
. Esto permite que unastruct
definición oculte un nombre en un ámbito externo y tiene algunas otras consecuencias. Además, C permite un mayor alcance para lasstruct
definiciones y las permite en declaraciones de tipo de retorno y tipo de argumento.C ++ es más exigente con los tipos en general. No permitirá que se asigne un número entero a un
enum
, y losvoid *
objetos no se pueden asignar a otros tipos de puntero sin una conversión. En C, es posible proporcionar un inicializador demasiado grande (char name[5] = "David"
donde C descartará el carácter nulo final).C89 se permite implícitamente
int
en muchos contextos y C ++ no. Esto significa que todas las funciones deben declararse en C ++, mientras que en C89 a menudo era posible asumirint
todo lo aplicable en la declaración de función.En C, es posible saltar del exterior de un bloque al interior utilizando una declaración etiquetada. En C ++, esto no está permitido si se salta una inicialización.
C es más liberal en el enlace externo. En C, una
const
variable global es implícitaextern
, y eso no es cierto en C ++. C permite que un objeto de datos global se declare varias veces sin unextern
, pero eso no es cierto en C ++.Muchas palabras clave de C ++ no son palabras clave en C o están
#define
d en encabezados C estándar.También hay algunas características antiguas de C que ya no se consideran de buen estilo. En C, puede declarar una función con las definiciones de los argumentos después de la lista de argumentos. En C, una declaración como
int foo()
significa quefoo()
puede tomar cualquier número de cualquier tipo de argumentos, mientras que en C ++ es equivalente aint foo(void)
.Eso parece cubrir todo, desde Stroustrup.
fuente
Si usa gcc, puede usar la advertencia
-Wc++-compat
para darle advertencias sobre el código C que es dudoso en C ++ de alguna manera. Actualmente se utiliza en gcc y ha mejorado mucho recientemente (tal vez pruebe una versión nocturna para obtener lo mejor que pueda).(Esto no responde estrictamente a la pregunta, pero a la gente le puede gustar).
fuente
Creo que la mayor diferencia es que este es un archivo fuente C válido:
Tenga en cuenta que no he declarado en
foo
ningún lado.Aparte de las diferencias de idioma, C ++ también realiza algunos cambios en la biblioteca que heredó de C, por ejemplo, algunas funciones devuelven en
const char *
lugar dechar *
.fuente
s,C,C89,
y tenga en cuenta que es un archivo fuente C99 no válido.Consulte también la entrada de preguntas frecuentes de C ++ .
fuente
Algunas de las respuestas aquí cubren diferencias de sintaxis que harían que los compiladores de C ++ fallaran en el código fuente C89 (o C99). Sin embargo, existen algunas diferencias sutiles de idioma que son legales en ambos idiomas pero que producirían un comportamiento diferente. La
sizeof (char)
diferencia que mencionó Naveen es un ejemplo, pero escriba un programa que imprima "C" si se compila como un programa (ANSI) C, y "C ++" si se compila como un programa C ++ enumera algunos otros.fuente
Los compiladores de C generalmente permitieron un pequeño corte de esquina que C ++ no permite. C ++ es mucho más estricto que C. Y, en general, algunas de estas diferencias dependen del compilador. g ++ permite algunas cosas que el compilador Intel C ++ no permite, por ejemplo. Incluso el código C bastante bien escrito no se compilará con un compilador C ++ moderno.
fuente
No puede comparar idiomas solo por sintaxis. Si lo hace, tal vez pueda ver a C como un subconjunto de C ++. En mi opinión, el hecho de que C ++ sea OO (y C no) es suficiente para decir que C y C ++ son lenguajes diferentes.
fuente