'>

Compatibilité de C et C + +

Le C et le C + + langages de programmation sont étroitement liés. C + + est née de C, comme il a été conçu pour être la source et la liaison compatible avec C. [1] Pour cette raison, les outils de développement pour les deux langues (comme les IDE et les compilateurs) sont souvent intégrés dans un seul produit, avec le programmeur en mesure de préciser C ou C + + comme leur langue d'origine. Toutefois, en raison des différences sémantiques mineures, la plupart des programmes C non triviales ne compiler que C + + code sans modification-C + + n'est pas un ensemble strict de C.
De même, C + + introduit de nombreuses fonctionnalités qui ne sont pas disponibles en C et en pratique presque tout le code écrit en C + + n'est pas conforme code C. Cet article, cependant, se concentre sur les différences qui causent conforme code C pour être mal formé code C + +, ou pour être conforme / bien formé dans les deux langues, mais à se comporter différemment en C et C + +.
Bjarne Stroustrup, le créateur du C + +, a suggéré [2] que les incompatibilités entre C et C + + doit être réduite autant que possible afin de maximiser l'interopérabilité entre les deux langues. D'autres ont soutenu que, puisque C et C + + sont deux langues différentes, la compatibilité entre eux est utile, mais pas indispensable, selon ce camp, les efforts pour réduire l'incompatibilité ne devrait pas entraver les tentatives d'améliorer chaque langue dans l'isolement. La raison officielle de la norme 1999 C (C99) "cautionne [d] le principe du maintien le plus grand sous-ensemble commun" entre C et C + + "tout en maintenant une distinction entre eux et en leur permettant d'évoluer séparément», et a déclaré que les auteurs étaient "contente de laisser C + + est la langue grand et ambitieux». [3]
Plusieurs ajouts de C99 sont ou ne sont pas pris en charge dans C + + ou en conflit avec C + + fonctionnalités, telles que les macros variadiques, les mots composés, initialisateurs désignés, des tableaux de longueur variable, et les types de nombres complexes indigènes. Le long long int type de données et de limiter qualification définis dans C99 n'ont pas été inclus dans le + +03 C standard, mais les compilateurs les plus courants tels que la GNU Compiler Collection, [4] Microsoft Visual C + + et Intel C + + Compiler leur a fourni comme une extension. Le type de données long long long avec des macros variadiques sont présents dans la nouvelle norme C + +, C + +11. D'autre part, C99 a réduit certains autres incompatibilités en incorporant C + + fonctionnalités telles que / / commentaires et déclarations et de code mixtes.
Constructions valables dans C mais pas en C + +
Une différence communément rencontrée est que C permet un void * pointer à être affecté à n'importe quel type de pointeur sans un casting, alors que C + + ne fait pas; cet idiome apparaît souvent dans le code C en utilisant l'allocation de mémoire malloc. Par exemple, ce qui suit est valable dans C mais pas C + +:
void * ptr;int * i = ptr; / * conversion implicite du void * en int ** /
ou similaire:
int * j = malloc (sizeof (int) * 5); / * conversion implicite du void * en int ** /
Afin de faire la compilation de code en C + +, il faut utiliser une conversion explicite:
void * ptr;int * i = (int *) ptr;int * j = (int *) malloc (sizeof (int) * 5);
Un autre problème de la portabilité du C au C + + sont les nombreux mots-clés supplémentaires que C + + introduit. Cela rend le code C qui les utilise comme des identifiants valides en C + +. Par exemple:
struct modèle{
    
int nouveau;
    
struct template * classe;};
est un code C valide, mais est rejetée par un compilateur C + +, puisque les mots-clés "template", "nouveau" et "classe" sont réservés.
Compilateurs C + + interdit l'utilisation de goto ou un commutateur de traverser une initialisation, comme dans le code C99 suivante:
vide fn (void){
  
goto Flack;
  
int i = 1;Flack:
  
;}
Il ya beaucoup d'autres syntaxes de C qui sont invalides ou se comportent différemment en C + +: [5]

    
L'opérateur virgule peut entraîner une "valeur L" (une quantité qui peut être utilisé pour le côté gauche d'une assignation) en C + +, mais pas en C.
    
C ne permet pas une donnée typedef être dupliqué dans la même portée, alors que C + + permet typedefs répétées.
    
constantes d'énumération (valeurs enum) sont toujours de type int en C, tandis que ce sont des types distincts de C + + et peut avoir une taille différente de celle de int.
    
Identificateurs C + + ne sont pas autorisés à contenir deux ou plusieurs traits de soulignement consécutifs dans n'importe quelle position. Identificateurs C ne sont pas autorisés à commencer par deux ou plusieurs traits de soulignement consécutifs, mais peuvent contenir dans d'autres positions.
    
C + + modifie également certaines fonctions de la bibliothèque C standard d'ajouter des qualificatifs const supplémentaires, par exemple strchr retourne char * en C et const char * en C + +.
    
Dans les deux C et C + + on peut définir les types struct imbriqués, mais la portée est interprétée différemment (en C + +, une structure imbriquée est définie uniquement dans le cadre / namespace de la structure externe).
    
Non-prototype (style «K & R») des déclarations de fonctions ne sont pas autorisés en C + +, mais ils ont également été désapprouvée dans C depuis 1990. De même, les déclarations de fonctions implicites (utilisant des fonctions qui n'ont pas été déclarés) ne sont pas autorisés en C + +, mais ont également été désapprouvée dans C depuis 1999.
    
C permet struct, union, et ENUM types doivent être déclarées dans les prototypes de fonction, alors que C + + ne fonctionne pas.
    
Un struct, union ou une déclaration enum en C + + en général se traduit par une typedef implicite du même nom, alors qu'en C il n'existe pas.
    
En C, un prototype de fonction sans arguments, par exemple, int foo ();, implique que les paramètres ne sont pas spécifiés. Par conséquent, il est légal de convoquer une telle fonction avec un ou plusieurs arguments, par exemple foo (42, "Bonjour le monde"). En revanche, en C + + d'un prototype d'une fonction sans arguments signifie que la fonction ne prend aucun argument et appelle une telle fonction avec des arguments est mal formé. En C, la bonne façon de déclarer une fonction qui ne prend aucun argument est d'utiliser «vide», comme dans int foo (void);.
    
C + + est plus stricte que C sur les affectations de pointeur que Jeter un qualificatif const (par exemple l'attribution d'un const int * valeur à un int * variable): en C + + ce n'est pas valide et génère une erreur de compilation (sauf si une conversion de type explicite est utilisée), [6 ] alors qu'en C, cela est permis (bien que de nombreux compilateurs émettent un avertissement).
Les constructions qui se comportent différemment en C et C + +
Il ya quelques constructions syntaxiques qui sont valables à la fois C et C + +, mais produire des résultats différents dans les deux langues.
Par exemple, les littéraux de caractères tels que 'a' sont de type int en C et de type char en C + +, ce qui signifie que sizeof 'a' donnera généralement des résultats différents dans les deux langues: en C + +, il sera 1, alors qu'en C il sera sizeof (int) qui, sur des architectures à 8 bits de large caractères sera d'au moins 2. Une autre conséquence de cette différence de genre, dans C 'a' sera toujours une expression signée, indépendamment de si oui ou non char est un type signé ou non, alors que pour C + + c'est la mise en œuvre du compilateur spécifique.
C + + traite implicitement toute const mondiale comme champ de fichier, sauf si elle est explicitement déclarée extern, contrairement à C dans laquelle externe est l'option par défaut. En revanche, les fonctions inline dans C sont de portée du fichier alors qu'ils ont une liaison externe par défaut dans C + +.
Plusieurs autres différences par rapport à la section précédente peut aussi être exploité pour créer du code qui compile dans les deux langues, mais se comporte différemment. Par exemple, la fonction suivante retourne des valeurs différentes en C et C + +:
extern int T;
 
int size (void){
    
struct T {int i; int j;};

    
retourner sizeof (T);
    
/ * C: retour sizeof (int)
     
* C + +: retour sizeof (struct T)
     
* /}
Cela est dû à C nécessitant une struct en face de balises de structure (et donc sizeof (T) fait référence à la variable), mais C + + permettant d'être omis (et donc sizeof (T) se réfère à la typedef implicite). Méfiez-vous que le résultat est différent lorsque la déclaration externe est placé à l'intérieur de la fonction: alors la présence d'un identifiant avec le même nom dans la portée de la fonction inhibe la typedef implicite qui prendra effet pour C + +, et le résultat pour C et C + + serait le même . Observez également que l'ambiguïté dans l'exemple ci-dessus est due à l'utilisation de la parenthèse avec l'opérateur sizeof. En utilisant sizeof T s'attendrait T est une expression et non pas un type, et donc l'exemple ne serait pas compiler avec C + +.
Les deux C99 et C + + ont un type booléen bool avec des constantes vrai et le faux, mais ils se comportent différemment. En C + +, bool est un type intégré et un mot clé réservé. En C99, un nouveau mot-clé, _Bool, est présenté comme le nouveau type booléen. Dans de nombreux aspects, il se comporte comme un unsigned int, mais les conversions d'autres types d'entiers ou des pointeurs toujours contraint à 0 et 1. Autre que pour les autres types non signés, et comme on pouvait s'y attendre pour un type booléen, une telle conversion est de 0 si et seulement si l'expression en question évalue à 0 et il est de 1 pour tous les autres cas. L'en-tête stdbool.h fournit macros bool, vrai et faux qui sont définis comme _Bool, 1 et 0, respectivement.Lier C et C + +
Alors que C et C + + maintenir un grand degré de compatibilité source, l'objet dépose produisent leurs compilateurs respectifs peuvent avoir d'importantes différences qui se manifestent quand on mélange C et C + + code. Notamment:

    
Compilateurs C ne nomment pas les symboles de calandre dans la façon dont compilateurs C + + font.
    
Selon le compilateur et l'architecture, il peut également être le cas que les conventions d'appel diffèrent entre les deux langues.
Pour ces raisons, de code C + + pour appeler une fonction foo C (), le code C + + doit prototyper foo () avec extern "C". De même, pour le code C pour appeler un C + + function bar (), le code C + + pour la barre () doit être déclarée avec extern "C".
Une pratique courante pour les fichiers d'en-tête pour maintenir à la fois C et C + + compatibilité est de faire sa déclaration soit extern "C" pour le champ de l'en-tête:
/ * Fichier d'en-tête foo.h * /# Ifdef __ cplusplus / * S'il s'agit d'un compilateur C + +, C utilisation lien * /extern "C" {# Endif
 
/ * Ces fonctions deviennent lien C * /vide foo ();
 
struct bar {/ * ... * /};
 
# Ifdef __ cplusplus / * S'il s'agit d'un compilateur C + +, C fin liens * /}# Endif
Les différences entre C et C + + conventions de liaison et d'appel peuvent également avoir des implications subtiles pour le code qui utilise des pointeurs de fonction. Certains compilateurs produisent du code non-travail si un pointeur de fonction déclarée extern points "C" à une fonction C + + qui n'est pas déclarée extern "C". [7]
Par exemple, le code suivant:
annuler my_function ();extern "C" void truc (void (* fn_ptr) (void));
 
bar void (){
   
foo (my_function);}
Utilisation de Sun Microsystems compilateur C + +, ce qui produit l'avertissement suivant:
$ CC-c test.cc"Test.cc", ligne 6: Avertissement (anachronisme): Formal argumentation fn_ptr de Typeexterne vide "C" (*) () dans l'appel à foo (externe vide "C" (*) ()) est passévoid (*) ().
C'est parce que my_function () n'est pas déclarée avec C de liaison et les conventions d'appel, mais est passé à la fonction foo C ().

Published By Drupal french Study