how - ¿Dónde no es C un subconjunto de C++?
how can c++ code call ac function (12)
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 cuando el código se compilará en C, pero no en C ++?
Algunas de las respuestas aquí cubren las diferencias de sintaxis que causarían que los compiladores C ++ fallaran en el código fuente C89 (o C99). Sin embargo, hay algunas diferencias de lenguaje sutiles que son legales en ambos idiomas pero que producirían un comportamiento diferente. La diferencia de sizeof (char)
que menciona Naveen es un ejemplo, pero Escriba un programa que imprimirá "C" si se compila como un programa (ANSI) C, y "C ++" si se compila como un programa C ++ enumera algunos otros.
C ++ también tiene nuevas palabras clave. El siguiente es código C válido pero no compilará en C ++:
int class = 1;
int private = 2;
int public = 3;
int virtual = 4;
En C ++, si declaras una struct
, union
o enum
, se puede acceder inmediatamente a su nombre sin ningún calificador:
struct foo { ... };
foo x; // declare variable
En C, esto no funcionará, porque los tipos así declarados viven en sus propios espacios de nombres distintos. Por lo tanto, debes escribir:
struct foo { ... };
struct foo x; // declare variable
Observe la presencia de struct
allí en la segunda línea. Tienes que hacer lo mismo para union
y enum
(usando sus respectivas palabras clave), o usa el truco typedef
:
typedef struct { ... } foo;
foo x; // declare variable
En consecuencia, puede tener varios tipos de diferentes tipos nombrados de la misma manera en C, ya que puede desambiguar:
struct foo { ... };
typedef enum { ... } foo;
struct foo x;
foo y;
Sin embargo, en C ++, si bien puede prefijar un nombre de struct
con la struct
palabra clave siempre que lo referencia, los espacios de nombres se combinan, por lo que el fragmento de C anterior no es válido. Por otro lado, C ++ hace específicamente una excepción para permitir que un tipo y un typedef para ese tipo tengan el mismo nombre (obviamente sin ningún efecto), para permitir el uso del truco typedef
sin cambios desde C.
En C, sizeof(''a'')
es igual a sizeof(int)
.
En C ++, sizeof(''a'')
es igual a sizeof(char)
.
Esto también depende de la variedad de C que estés usando. Stroustrup hizo C ++ tan compatible como pudo, y no más compatible, con los estándares ANSI de 1989 y 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 ++ cambió el próximo estándar de C ++ (probablemente el próximo año más o menos) para cumplir con 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 3ª edición con algo de material añadido):
''a''
es un int
en C, un char
en C ++.
El tamaño de una enumeración es int
en C, no necesariamente en C ++.
C ++ tiene //
comentarios al final de la línea, C no (aunque es una extensión común).
En C ++, una struct foo {
definition pone a foo
en el espacio de nombre global, mientras que en C debería llamarse struct foo
. Esto permite que una definición de struct
sombree un nombre en un ámbito externo y tiene algunas otras consecuencias. Además, C permite un mayor alcance para las definiciones de struct
, y las permite en declaraciones de tipos de declaraciones y argumentos.
C ++ es más quisquilloso con los tipos en general. No permitirá asignar un número entero a una enum
, y los objetos void *
no se pueden asignar a otros tipos de puntero sin un molde. En C, es posible proporcionar un inicializador sobregrande ( char name[5] = "David"
donde C descartará el carácter nulo final).
C89 permitió int
implícita en muchos contextos, y C ++ no lo hace. Esto significa que todas las funciones se deben declarar en C ++, mientras que en C89 a menudo se puede pasar asumiendo int
para todo lo aplicable en la declaración de la función.
En C, es posible saltar desde afuera de un bloque hacia adentro usando una declaración etiquetada. En C ++, esto no está permitido si se saltea una inicialización.
C es más liberal en vinculación externa. En C, una variable const
global es implícitamente extern
, y eso no es cierto en C ++. C permite declarar un objeto de datos global varias veces sin extern
, pero eso no es cierto en C ++.
Muchas palabras clave de C ++ no son palabras clave en C, o son #define
d en encabezados C estándar.
También hay algunas características antiguas de C que ya no se consideran un buen estilo. En C, puede declarar una función con las definiciones de argumento después de la lista de argumentos. En C, una declaración como int foo()
significa que foo()
puede tomar cualquier cantidad de cualquier tipo de argumentos, mientras que en C ++ es equivalente a int foo(void)
.
Eso parece cubrir todo desde Stroustrup.
Hay muchas cosas Solo un simple ejemplo (debería ser suficiente para demostrar que C no es un subconjunto propio de C ++):
int* test = malloc(100 * sizeof(int));
debería compilarse en C pero no en C ++.
La única diferencia más grande que creo es que este es un archivo fuente C válido:
int main()
{
foo();
}
Tenga en cuenta que no he declarado foo
ningún lado.
Además de las diferencias de idioma, C ++ también realiza algunos cambios en la biblioteca que heredó de C, por ejemplo, algunas funciones devuelven const char *
lugar de char *
.
Los compiladores C generalmente permiten un pequeño corte de esquina que C ++ no hace. 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 hace, por ejemplo. Incluso el código C bastante bien escrito no compilará con un compilador moderno de C ++.
No puede comparar idiomas solo por sintaxis. Si lo haces, tal vez puedas ver a C como un subconjunto de C ++. En mi opinión, el hecho de que C ++ sea OO (y C no lo es) es suficiente para decir que C y C ++ son idiomas diferentes.
Si usa gcc, puede usar la advertencia -Wc++-compat
para advertirle de algún modo sobre el código C que es dudoso en C ++. Actualmente se usa en gcc, y ha mejorado mucho recientemente (quizás intente una versión nocturna para obtener lo mejor que pueda).
(Esto no responde estrictamente a la pregunta, pero a la gente le puede gustar).
Si compara C89
con C++
, aquí hay un par de cosas
No hay definiciones tentativas en C ++
int n;
int n; // ill-formed: n already defined
int [] e int [N] no son compatibles (no hay tipos compatibles en C ++)
int a[1];
int (*ap)[] = &a; // ill-formed: a does not have type int[]
Sin estilo de definición de función K & R
int b(a) int a; { } // ill-formed: grammar error
La estructura anidada tiene un alcance de clase en C ++
struct A { struct B { int a; } b; int c; };
struct B b; // ill-formed: b has incomplete type (*not* A::B)
Sin valor predeterminado int
auto a; // ill-formed: type-specifier missing
C99 agrega muchos otros casos
Sin manejo especial de especificadores de declaración en dimensiones de matriz de parámetros
// ill-formed: invalid syntax
void f(int p[static 100]) { }
Sin matrices de longitud variable
// ill-formed: n is not a constant expression
int n = 1;
int an[n];
Ningún miembro de matriz flexible
// ill-formed: fam has incomplete type
struct A { int a; int fam[]; };
Sin restricción de calificación para ayudar a aliasing analysis
// ill-formed: two names for one parameter?
void copy(int *restrict src, int *restrict dst);
#include <stdio.h>
int new (int n) {
return n/2;
}
int main(void) {
printf("%d/n", new(10));
return 0;
}
Ver también la entrada de C ++ FAQ .