J'ai lu dans beaucoup de livres que C est un sous-ensemble de C ++.
Certains livres disent que C est un sous-ensemble de C ++, à l' exception des petits détails .
Dans quels cas le code se compilera-t-il en C, mais pas en C ++?
Si vous comparez C89
avec, C++
voici quelques choses
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 ajoute de nombreux autres boîtiers
// 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;
est un TU légal en C, mais pas en C ++.auto a;
est valide dans la dernière révision standard C ++.a
?auto x;
n'est pas valide dans la dernière révision, mais par exempleauto x = 0;
. J'ai été un peu choqué au début :)En C,
sizeof('a')
est égal àsizeof(int)
.En C ++,
sizeof('a')
est égal àsizeof(char)
.la source
'a'
est unint
. En C ++,'a'
est unchar
.C ++ a également de nouveaux mots clés. Ce qui suit est du code C valide mais ne sera pas compilé sous C ++:
la source
Il y a plein de choses. Juste un exemple simple (cela devrait suffire à prouver que C n'est pas un sous-ensemble approprié de C ++):
devrait compiler en C mais pas en C ++.
la source
int*
.void *
, qui en C peut être assigné à n'importe quel type de pointeur, et C ++ ne peut être assigné à aucun autre type de pointeur.En C ++, si vous déclarez un
struct
,union
ouenum
, son nom est immédiatement accessible sans qualification:En C, cela ne fonctionnera pas, car les types ainsi déclarés vivent dans leurs propres espaces de noms distincts. Ainsi, vous devez écrire:
Remarquez la présence de
struct
là sur la deuxième ligne. Vous devez faire de même pourunion
etenum
(en utilisant leurs mots-clés respectifs), ou utiliser l'typedef
astuce:Par conséquent, vous pouvez avoir plusieurs types de types différents nommés de la même manière en C, car vous pouvez lever l'ambiguïté:
En C ++, cependant, alors que vous pouvez préfixer un
struct
nom avec un mot-cléstruct
chaque fois que vous le référencez, les espaces de noms sont fusionnés, et donc l'extrait de code C ci-dessus n'est pas valide. D'autre part, C ++ fait spécifiquement une exception pour permettre à un type et à un typedef pour ce type d'avoir le même nom (évidemment sans effet), pour permettre l'utilisation detypedef
truc inchangé depuis C.la source
struct
,union
etenum
) partagent le même espace de noms. Un meilleur exemple seraitstruct foo { ... }; typedef enum { ... } foo;
Cela dépend également de la variété de C que vous utilisez. Stroustrup a rendu C ++ aussi compatible qu'il le pouvait, et non plus compatible, avec les normes ANSI de 1989 et ISO de 1990, et la version de 1995 n'a rien changé. Le comité C est allé dans une direction quelque peu différente avec la norme de 1999, et le comité C ++ a changé la prochaine norme C ++ (probablement sortie l'année prochaine environ) pour se conformer à certains des changements.
Stroustrup répertorie les incompatibilités avec C90 / C95 dans l'annexe B.2 de "The C ++ Programming Language", Special Edition (qui est la 3e édition avec du matériel supplémentaire):
'a'
est unint
en C, unchar
en C ++.La taille d'une énumération est
int
en C, pas nécessairement en C ++.C ++ a des
//
commentaires à la fin de la ligne, pas C (bien que ce soit une extension courante).En C ++, une
struct foo {
définition placefoo
dans l'espace de noms global, tandis qu'en C, il faudrait l'appelerstruct foo
. Cela permet à unestruct
définition d'observer un nom dans une portée externe et a quelques autres conséquences. De plus, C permet une plus grande portée pour lesstruct
définitions et les autorise dans les déclarations de type de retour et de type d'argument.C ++ est plus difficile à propos des types en général. Il ne permet pas d'affecter un entier à un
enum
, et lesvoid *
objets ne peuvent pas être affectés à d'autres types de pointeurs sans conversion. En C, il est possible de fournir un initialiseur surdimensionné (char name[5] = "David"
où C le caractère nul de fin).C89 autorisé implicitement
int
dans de nombreux contextes, et C ++ ne le fait pas. Cela signifie que toutes les fonctions doivent être déclarées en C ++, alors qu'en C89, il était souvent possible de se débrouiller en supposantint
tout ce qui est applicable dans la déclaration de fonction.En C, il est possible de sauter de l'extérieur d'un bloc vers l'intérieur en utilisant une instruction étiquetée. En C ++, cela n'est pas autorisé s'il ignore une initialisation.
C est plus libéral en matière de liens externes. En C, une
const
variable globale est implicitementextern
, et ce n'est pas vrai en C ++. C permet à un objet de données global d'être déclaré plusieurs fois sansextern
, mais ce n'est pas le cas en C ++.De nombreux mots-clés C ++ ne sont pas des mots-clés en C ou sont
#define
d dans les en-têtes C standard.Il existe également des fonctionnalités plus anciennes de C qui ne sont plus considérées comme du bon style. En C, vous pouvez déclarer une fonction avec les définitions d'arguments après la liste d'arguments. En C, une déclaration comme
int foo()
signifie quefoo()
peut prendre n'importe quel nombre d'arguments de n'importe quel type, alors qu'en C ++, c'est équivalent àint foo(void)
.Cela semble couvrir tout de Stroustrup.
la source
Si vous utilisez gcc, vous pouvez utiliser l'avertissement
-Wc++-compat
pour vous donner des avertissements sur le code C qui est douteux en C ++ d'une certaine manière. Il est actuellement utilisé dans gcc lui-même, et il s'est beaucoup amélioré récemment (essayez peut-être une version nocturne pour obtenir le meilleur possible).(Cela ne répond pas strictement à la question, mais les gens pourraient l'aimer).
la source
La plus grande différence que je pense est qu'il s'agit d'un fichier source C valide:
Notez que je n'ai déclaré
foo
nulle part.Mis à part les différences de langage, C ++ apporte également des modifications à la bibliothèque dont il a hérité de C, par exemple certaines fonctions retournent à la
const char *
place dechar *
.la source
s,C,C89,
et noter qu'il s'agit d'un fichier source C99 non valide.Voir également l'entrée FAQ C ++ .
la source
Un certain nombre de réponses ici couvrent les différences de syntaxe qui entraîneraient l'échec des compilateurs C ++ sur le code source C89 (ou C99). Cependant, il existe des différences linguistiques subtiles qui sont légales dans les deux langues, mais qui entraîneraient un comportement différent. La
sizeof (char)
différence mentionnée par Naveen est un exemple, mais Ecrire un programme qui affichera «C» s'il est compilé en tant que programme C (ANSI) et «C ++» s'il est compilé en tant que programme C ++ en énumère d'autres.la source
Les compilateurs C permettaient généralement une petite coupe de coin, contrairement à C ++. C ++ est beaucoup plus strict que C. Et généralement, certaines de ces différences dépendent du compilateur. g ++ autorise certaines choses que le compilateur Intel C ++ ne permet pas, par exemple. Même un code C assez bien écrit ne sera pas compilé avec un compilateur C ++ moderne.
la source
Vous ne pouvez pas comparer les langues uniquement par syntaxe. Si vous faites cela, vous pouvez peut-être voir C comme un sous-ensemble de C ++. À mon avis, le fait que C ++ soit OO (et C ne l'est pas) suffit à dire que C et C ++ sont des langages différents.
la source