ventajas sobre similitudes programacion lenguajes espaƱol entre cuadro comparativo analisis c++ c gcc g++

sobre - similitudes entre java y c++



Compatibilidad de compilaciĆ³n de C vs C++: no nombra un tipo (3)

Parece que tienes un archivo de encabezado que es ilegal en C ++, por lo que no puedes #include en el código compilado como C ++. Si no puede efectuar un cambio en el archivo del encabezado de la biblioteca (por ejemplo, quejándose con su proveedor de la biblioteca), la opción más sencilla es escribir un contenedor delgado compatible con C ++ alrededor de la biblioteca:

Para aislar su código C ++ contra el encabezado C, cree un Wrapper.h Wrapper.c , donde .h es válido para su inclusión en C ++, no incluye header.h , y proporciona todos los tipos y funciones que necesita para la interacción de la biblioteca. . Luego, en el .c , puede #include "header.h" e implementar todas las llamadas (y lo que sea necesario para convertir de forma segura entre los tipos). Obviamente, esto tendría que compilarse como C, no como C ++.

Estoy tratando de usar la biblioteca de un proveedor en combinación con mi aplicación C ++. La biblioteca se basa en gran medida en C, que normalmente no es un problema con la opción extern "C" , pero me encontré con un problema que el compilador de C ++ no acepta.

Simplifiqué mi código en los siguientes archivos de ejemplo. header.h representa un encabezado de la biblioteca de suppier, main.c / cpp son mis propios archivos. Mi aplicación real es una aplicación de C ++, por lo que quiero que funcione con main.cpp.

header.h (note la línea 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

C Principal:

#include <stdio.h> #include "header.h" int main() { union teststruct a; a.u64=5; printf("%x/n", a.u64); return 0; }

main.cpp (igual que main.c pero con una declaración extern "C" adicional):

#include <stdio.h> extern "C" { #include "header.h" } int main() { union teststruct a; a.u64=5; printf("%x/n", a.u64); return 0; }

Compilando main.c usando la línea

gcc -o test main.c

Se compila sin problemas. Sin embargo, compilando la versión de C ++ usando el compilador g ++ con el comando

g++ -o test main.cpp

da los siguientes errores de compilación:

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; ^

El problema es que el proveedor usó el mismo nombre (u64) tanto para el tipo como para el nombre de la variable, lo que parece una mala idea, pero parece que gcc lo acepta. No quiero cambiar la biblioteca (es decir, header.h) ya que es muy grande, esto ocurre mucho en el código y ocasionalmente recibo actualizaciones para él. ¿Hay una manera de hacer que g ++ acepte esta combinación, o una manera de modificar main.cpp para que se compile sin cambiar header.h?


Si su única incompatibilidad entre C y C ++ es la única, debería poder convertir header.h a un archivo de encabezado compatible con C ++ mediante programación, header.hpp nombre algo así como header.hpp . Y luego puedes convertir las versiones más nuevas de la misma manera.

Los errores del compilador le dicen todo sobre qué y dónde se debe cambiar:

header.h:11:9: error: ‘u64’ does not name a type

  1. Abrir header.h ;
  2. Busque la posición 11: 9;
  3. Insertar :: allí;
  4. Repetir para todos does not name a type error de does not name a type .

Un poco de procesamiento de cadenas y se hace.

PS: Los convertidores de C a C ++ pueden hacer eso también.


teststruct define un alcance en C ++. Usted puede formar el id calificado teststruct::u64 . Por lo tanto, las reglas de idioma para la búsqueda de nombres cuentan para eso, permitiendo a los miembros de clases y uniones ocultar los identificadores en el ámbito externo. Una vez u64 u64; se introduce, el u64 no calificado no puede referirse al global ::u64 , solo el miembro. Y el miembro no es un tipo.

En C union teststruct no define un alcance. El campo solo se puede usar en el acceso de miembros, por lo que nunca puede surgir un conflicto. Como tal, el campo no necesita ocultar el identificador de tipo de alcance de archivo.

Por lo que puedo decir, no hay nada que puedas hacer para solucionarlo fácilmente. Esta biblioteca (que es una biblioteca de C perfectamente válida), no es una biblioteca de C ++ válida. No es diferente si se usara new o try como nombres de variables. Necesita ser adaptado.