53 votes

Incompatibilité de compilation C vs C ++ - ne nomme pas de type

Je suis en train d'utiliser un fournisseur de la bibliothèque en combinaison avec mon application C++. La bibliothèque est en grande partie basé sur le C, qui n'est normalement pas un problème avec l' extern "C" option, mais j'ai rencontré un problème que le compilateur C++ de ne pas accepter.

J'ai simplifié mon code dans l'exemple suivant fichiers. l'en-tête.h représente un en-tête de la suppier bibliothèque principale.c/rpc sont mes propres fichiers. Mon application est une application C++, donc je veux le faire fonctionner avec main.cpp.

l'en-tête.h (notez la ligne u64 u64;):

#ifndef HEADER_H
#define HEADER_H

#include <stdint.h>

typedef uint64_t u64;

union teststruct {
    u64 u64;
    struct {
        u64 x:32;
        u64 y:32;
    } s;
};

#endif

principal.c:

#include <stdio.h>
#include "header.h"

int main() {
    union teststruct a;
    a.u64=5;
    printf("%x\n", a.u64);

    return 0;
}

main.cpp (même en tant que principal.c mais avec un supplément de extern "C" déclaration):

#include <stdio.h>

extern "C" {
#include "header.h"
}

int main() {
    union teststruct a;
    a.u64=5;
    printf("%x\n", a.u64);

    return 0;
}

La compilation principal.c à l'aide de la ligne de

gcc -o test main.c

compile sans problèmes. Cependant, la compilation de la version C++ en utilisant le compilateur g++ avec la commande

g++ -o test main.cpp

donne à la suite d'erreurs du compilateur:

In file included from main.cpp:12:0:
header.h:11:9: error: ‘u64' does not name a type
         u64 x:32;
         ^
header.h:12:9: error: ‘u64' does not name a type
         u64 y:32;
         ^

Le problème est que le fournisseur a utilisé le même nom (u64) pour à la fois le type et le nom de la variable, ce qui semble une mauvaise idée, pour commencer, mais gcc apparemment l'accepte. Je ne veux pas changer la bibliothèque (c'est à dire d'en-tête.h) qu'il est très grand,cela se produit beaucoup dans le code, et je reçois parfois des mises à jour pour elle. Est-il un moyen de faire de g++ accepter cette combinaison, ou un moyen de modifier main.cpp pour le faire compiler sans modification de l'en-tête.h?

48voto

StoryTeller Points 6139

teststruct définit un champ d'application en C++. Vous pouvez former la personne id teststruct::u64. Donc, les règles de la langue pour la recherche d'un nom de compte pour que, en permettant à des membres de classes et les syndicats afin de masquer les identifiants à l'extérieur de la portée. Une fois u64 u64; est introduit, l'incompétent u64 ne peut pas se référer à l'global ::u64, seul le membre. Et le membre n'est pas un type.

Dans C union teststruct ne permet pas de définir un champ d'application. Le champ ne peut être utilisé dans l'accès des membres, de sorte qu'il peut ne jamais se produire un conflit. En tant que tel, le champ ne doivent pas masquer la portée de l'identificateur de type.

Il n'y a rien, autant que je peux dire, que vous pouvez faire afin de travailler facilement autour d'elle. Cette bibliothèque (ce qui est parfaitement valide de la bibliothèque C), n'est pas une bibliothèque C++. Pas différent que s'il utilisait new ou try comme noms de variable. Il doit être adapté.

39voto

Max Langhof Points 19174

Il semble que vous avez un fichier d'en-tête qui est illégal en C++, donc vous ne pouvez pas #include dans le code compilé comme le C++. Si vous ne pouvez pas l'effet d'un changement dans la bibliothèque de l'en-tête de fichier (par exemple, en se plaignant à votre bibliothèque fournisseur) puis l'option la plus simple est d'écrire un mince C++compatible wrapper autour de la bibliothèque:

Pour isoler votre code C++ à l'encontre de l'en-tête C, créer un Wrapper.h et Wrapper.c, où l' .h est valable pour l'inclusion en C++, ne pas inclure header.h, et fournit tous les types et les fonctions que vous avez besoin pour la bibliothèque de l'interaction. Puis, en .c, vous pouvez #include "header.h" et de mettre en œuvre tous les appels (et tout ce que vous devez faire pour convertir en toute sécurité entre les types). Ce serait évidemment être compilé comme le C, pas du C++.

3voto

Si votre mentionnés à l'incompatibilité entre le C et le C++ est le seul, vous devriez être en mesure de convertir header.h de C++ compatible fichier d'en-tête de la programmation, le nom de quelque chose comme header.hpp. Et ensuite, vous pouvez convertir des versions plus récentes de la même façon.

Les erreurs de compilation tout vous dire sur quoi et où doit être modifié:

header.h:11:9: error: ‘u64' does not name a type
  1. Ouvrez header.h;
  2. Position de recherche 11:9;
  3. Insérez :: y;
  4. Répétez l'opération pour tous les does not name a type d'erreur.

Certains de la chaîne de traitement et c'est fait.

PS: C, C++ convertisseurs en mesure de le faire aussi.

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