2008-11-20 7 views
10

Le commentaire à this answer m'a fait me demander. J'ai toujours pensé que C était un sous-ensemble correct de C++, c'est-à-dire que tout code C valide est un code C++ valide par extension. Ai-je tort à ce sujet? Est-il possible d'écrire un programme C valide qui n'est pas un code C++ valide?Le code C est-il toujours considéré comme C++?

EDIT: Ceci est vraiment similaire à, mais pas une copie exacte de this question.

+0

Bill J'ai spécialisé le sujet de l'autre question, parce que le sujet n'était pas représentatif de la question. –

+0

Je pense que vous avez raison. Le but de la question (et les réponses données) est assez différent pour le garder ouvert. –

Répondre

27

En général, oui le code C est considéré comme du code C++.

Mais C n'est pas un sous-ensemble correct au sens strict. Il y a quelques exceptions.

Voici quelques choses valables en C qui ne sont pas valides en C++:

int *new;//<-- new is not a keyword in C 
char *p = malloc(1024); //void * to char* without cast 

Il y a d'autres exemples aussi, mais vous voyez l'idée. J'ai déjà écrit une réponse plus complète dans une question similaire here.

+1

Wow, deux minutes! C'est comme si vous vous contentiez d'attendre que quelqu'un pose cette question. :) –

+1

J'ai été rafraichissant non stop pendant 37 jours, et finalement vous l'avez demandé;) –

+0

Techniquement, ils compilent ensemble (comme indiqué ci-dessus). Mais écrire du code C dans un fichier C++ (alias C avec des classes) ne veut pas dire que c'est du C++. Les styles pour chaque langue sont si radicalement différents, passer de C à C++, c'est comme apprendre une nouvelle langue. Passer du C++ au C est juste trop douloureux. –

2
typedef struct { 
    int a, b, c; 
} st; 

st s = { 
    .a = 1, 
    .b = 2, 
}; 

Ce code valide est de C qui ne compile pas en plus compilateurs C++. Cela ne fait pas partie des spécifications C++ autant que je sache. Cependant, certains compilateurs C++ sont "libéraux" avec certaines parties du langage et permettent des choses qu'ils ne devraient pas faire, tout comme beaucoup manquent quelques nuances qui sont dans la spécification mais presque jamais utilisées.

+0

Je pense que la raison pour laquelle les compilateurs accepteront ceci est si vous mettez le drapeau de compatibilité C99, ou ne le désactivez pas . –

1

Je pense qu'il peut être plus correct de dire que ANSI C est un sous-ensemble de C++. Non K & R C.

+0

K & R C (2ème édition assis en face de moi) est ANSI C. –

+1

K & R C est le terme familier pour C pré-standard (K & R 1ère Edn). –

+0

@Jonathan: Merci. Je ne le savais pas. –

5

Un couple d'autres choses qui sont valides C mais pas C++:

int func(); 
func(0,0); //Error in C++, but not in C 

Aussi ne sous-estimons pas l'impact de C++ ayant plusieurs mots-clés:

int new; //Obviously an error in C++ 
+0

Je suis sûr que votre premier exemple est faux. Comeau le rejette. Si vous fournissez une liste de paramètres, vous devez l'honorer. Si vous laissez la liste des paramètres vide, vous pouvez transmettre tous les paramètres souhaités. –

+0

Vous avez raison. Je l'ai édité. –

5

Une chose qui définit les deux à part et revient dans le développement au jour le jour est le couplage et le mangling nom de la fonction. Une fonction C compilée avec un compilateur C n'est pas accessible à C++ sauf si le prototype est balisé avec extern "C".

7

Quelques autres:

C permet des appels récursifs à principal, C++ ne

char foo[3] = "abc" est C juridique, et non C++

sizeof('A') == sizeof(int) est vrai en C et faux en C++

Il y a encore plus de changements avec C99

Editer: J'ai trouvé un message que énumère la majorité des différences.http://c-faq.com/misc/cplusplus.nr.html

Résumé des raisons pour lesquelles C est pas bon sous-ensemble de C++:

  1. conversion automatique de void * à tout objet/type incomplet
  2. nouveaux mots-clés (un certain nombre de ceux-ci)
  3. en raison de struct s devenir portée
  4. en raison de struct étiquettes devenant typedef s
  5. en raison de prototypes étant nécessaire
  6. int implicites règles
  7. appel récursif à main
  8. En raison de // commentaires
  9. en raison de caractères littéraux étant le type char et non int etc.
+0

Intéressant, je ne savais pas à propos de tous les 3 d'entre eux. Avez-vous une référence pour C++ ne permettant pas les appels récursifs à la main? g ++ ne s'en plaindra que si j'ajoute le drapeau -pedantic. –

+0

Je ne trouve pas de référence à cela, je me souviens juste que ça a beaucoup été vu dans comp.lang.c quand les gens sont venus chercher de l'aide avec C/C++, ce qui a fait que les habitués se sont écriés: ! " –

+1

Notez que // est autorisé dans C99 - qui est le standard C actuel. –

12

Notez également que C99 ajoute plusieurs fonctionnalités qui ne sont pas autorisés en C++ (ou sont uniquement pris en charge à l'aide d'extensions de fournisseur), tels que les types de données intégrés _Complex et _Imaginary, variables gth arrays (tableaux dimensionnés au moment de l'exécution plutôt qu'à la compilation), membres de tableau flexibles (tableaux déclarés en tant que dernier membre d'une structure pouvant contenir un nombre indéterminé d'éléments), et plus encore.

Pour la liste exhaustive des incompatibilités entre C et C++, y compris les modifications avec C99, voir http://david.tribble.com/text/cdiffs.htm.