54 votes

Quelles sont les différences incompatibles entre C (99) et C ++ (11)?

Cette question a été déclenchée par replie(s) à un poste de Herb Sutter , où il a expliqué MME la décision de ne pas soutenir/faire un compilateur C99, mais juste aller avec le C(99) fonctions du C++(11) la norme de toute façon.

Un intervenant a répondu:

(...) C est important et mérite au moins un peu d'attention.

Il y a BEAUCOUP de code existant qui est valide en C, mais n'est pas valide en C++. Ce code n'est pas susceptible d'être réécrite (...)

Depuis que je programme uniquement en MS C++, je ne sais vraiment pas "pure", C bien, c'est à dire que j'ai pas de photo de ce que les détails du C++le langage que j'utilise ne sont pas dans C(99) et j'ai peu d'indices où certains C99 code ne fonctionnerait pas dans un compilateur C++.

Notez que je sais sur le C99 seulement restrict mot clé qui me semble très étroit et environ de longueur variable-tableaux (dont je ne suis pas sûr de la façon généralisée ou ils sont importants).

Aussi, je suis très intéressé de savoir si il y a d'importantes différences sémantiques ou de pièges, qui est, C(99) de code qui permettra de compiler en C++(11), mais faire quelque chose de différent avec le compilateur C++ qu'avec le compilateur C.


Liens rapides: ressources Externes à partir des réponses:

29voto

Dietrich Epp Points 72865

Il y a un tas d'incompatibilités qui ont été autour depuis des siècles (C90 ou plus tôt), ainsi que d'un tas de fonctionnalités intéressantes dans C99 et C11. Ce sont tous sur le dessus de ma tête.

// Valid C
int *array = malloc(sizeof(*array) * n);

// Valid C and valid C++, extra typing, it's always extra typing...
int *array = (int *) malloc(sizeof(*array) * n);

// Valid C++
int *array = new int[n];

C99 est sympa et C programmeurs partout dans le monde devrait l'utiliser

Les nouvelles fonctionnalités en C99 sont très agréable pour la programmation en général. Blaise et restrict ne le sont pas (à mon avis) ciblés pour un usage général, mais surtout pour apporter FORTRAN et numérique programmeurs de C (bien qu' restrict aide à la autovectorizer). Depuis tout conforme programme qui utilise restrict fonctionnera exactement de la même manière (mais peut-être pas aussi rapide) si vous #define restrict en haut de la fiche, c'est pas une grosse affaire. VLAs sont assez rares dans la nature, il semble.

Flexible membres du groupe peut être sympa. Notez que ce ne sont PAS les mêmes que la longueur variable des tableaux! Les gens ont été en utilisant ce truc depuis des années, mais le soutien officiel signifie moins de frappe et il nous permet aussi de faire constantes au moment de la compilation. (L'ancien était d'avoir un tableau de taille 1, mais lors du calcul de la taille d'allocation est un véritable peine.)

struct lenstr {
    unsigned length;
    char data[];
};
// compile time constant
const struct lenstr hello = { 12, "hello, world" };

Désigné initialiseurs. Permet d'économiser beaucoup de la saisie.

struct my_struct { int a; char *b; int c; const char *d; };
struct my_struct x = {
    .a = 15,
    .d = "hello"
    // implicitly sets b = NULL and c = 0
};
int hex_digits[256] = { ['0'] = 0, ['1'] = 1, ['2'] = 2, /* etc */ ['f'] = 15 };

L' inline mot-clé se comporte différemment, vous pouvez choisir l'unité de traduction obtient un non-inline version d'une fonction déclarées en ligne par l'ajout d'une déclaration extern à cette unité.

Composé de littéraux.

struct point { float x; float y; };
struct point xy_from_polar(float r, float angle)
{
    return (struct point) { cosf(angle) * r, sinf(angle) * r };
}

L' snprintf fonction est probablement dans mon top 10 des plus utiles de la bibliothèque de fonctions en C. Il n'est pas seulement manquant à partir de C++, mais le MSVC runtime fournit uniquement une fonction appelée _snprintf, ce qui n'est pas garanti pour ajouter un NUL de terminaison de la chaîne. (snprintf est en C++11, mais encore remarquablement absent de la MSVC C runtime.)

Anonyme les structures et les syndicats (C11, mais GCC extension depuis toujours) (anonyme syndicats sont apparemment en C++03, pas de MSVC support en C mode):

struct my_value {
    int type;
    union {
        int as_int;
        double as_double;
    }; // no field name!
};

Comme vous pouvez le voir, beaucoup de ces fonctions seulement vous faire économiser beaucoup de temps de frappe (composé de littéraux), ou de rendre les programmes plus facile à déboguer (flexible membres du groupe), de le rendre plus facile pour éviter les erreurs (désigné initializers / oublier d'initialiser les champs de structure). Ce ne sont pas des changements radicaux.

Pour les différences sémantiques, je suis sûr que l'aliasing règles sont différentes, mais la plupart des compilateurs sont suffisamment malléable ces jours, je ne suis pas sûr comment vous pouvez construire un cas de test à démontrer. La différence entre le C et le C++ que tout le monde est atteint pour le vieux - sizeof('a') expression, qui est toujours 1 pour le C++, mais généralement de 4 sur 32 bits, le système de climatisation. Mais personne ne se soucie de ce que sizeof('a') est de toute façon. Toutefois, il existe certaines garanties dans le standard C99 qui codifient les pratiques existantes.

Prenez le code suivant. Il utilise un truc commun pour la définition des types d'union dans C sans perdre de l'espace de stockage supplémentaire. Je pense que c'est sémantiquement valide C99 et je pense que c'est sémantiquement douteux, C++, mais j'ai peut-être tort.

#define TAG_FUNKY_TOWN 5
struct object { int tag; };
struct funky_town { int tag; char *string; int i; };
void my_function(void)
{
    struct object *p = other_function();
    if (p->tag == TAG_FUNKY_TOWN) {
        struct funky_town *ft = (struct funky_town *) p;
        puts(ft->string);
    }
}

C'est une honte, si. Le MSVC générateur de code est sympa, dommage qu'il n'y a pas C99 front-end.

26voto

Christoph Points 64389

Si vous démarrez à partir de la commune sous-ensemble de C et C++, parfois appelé clean C (ce qui n'est pas tout à fait C90), vous avez à considérer 3 types d'incompatibilités:

  1. Supplémentaires C++ featues qui font juridique C illégal C++

    Les exemples de ce sont C++ mots-clés qui peuvent être utilisés comme identificateurs en C ou en conversion implicite en C, mais nécessitent une conversion explicite en C++.

    C'est probablement la raison principale pourquoi Microsoft est toujours livré un C frontend à tous: sinon, héritage de code qui ne compile pas que C++ doit être réécrite.

  2. C supplémentaires caractéristiques qui ne font pas partie de C++

    Le langage C n'a pas arrêter d'évoluer après le C++ a été divisée en deux. Quelques exemples sont de longueur variable des tableaux, désigné initialiseurs et restrict. Ces caractéristiques peuvent être très utiles, mais ne font pas partie du C++ standard, et certains d'entre eux ne sera probablement jamais le faire.

  3. Les fonctionnalités qui sont disponibles dans les deux C et C++, mais ont des sémantiques différentes

    Un exemple de ceci serait le couplage de l' const d'objets ou d' inline fonctions.

Une liste d'incompatibilités entre la C99 et C++98 peut être trouvé ici (ce qui a déjà été mentionnée par Mat).

Tandis que le C++11 et C11 se rapproche sur certains points (variadic macros sont maintenant disponibles en C++, de longueur variable, les tableaux sont maintenant une option de langage C), la liste des incompatibilités a augmenté (par exemple générique sélections en C et l' auto type-rédacteur en C++).

En aparté, tandis que Microsoft a pris un peu de chaleur pour la décision d'abandonner C (ce qui n'est pas récente, dans la mesure où je ne connais personne dans la communauté open source a effectivement pris des mesures pour faire quelque chose à ce sujet: Il serait tout à fait possible de fournir de nombreuses fonctionnalités modernes C par l'intermédiaire d'un C-à-compilateur C++, en particulier si vous considérez que certains d'entre eux sont facile à implémenter. Ceci est possible dès maintenant en utilisant Comeau C/C++, qui supporte le C99.

Cependant, il n'est pas vraiment une question pressante: Personnellement, je suis très à l'aise avec l'utilisation de GCC et Clang sur Windows, et il y a des alternatives propriétaires de MSVC ainsi, par exemple, Pelles C ou Intel compilateur.

2voto

bames53 Points 38303

En C ++, définir un membre d'une union et accéder à la valeur d'un autre membre constitue un comportement indéfini, alors que ce n'est pas indéfini dans C99.

Il y a beaucoup d'autres différences listées sur la page wikipedia.

2voto

emsr Points 4616

Je mentionnerai "C.1 C ++ et ISO C" du standard C ++11 . Ce document porte coup sur coup chaque différence et son impact sur le développement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X