2012-09-22 25 views
13

Possible Duplicate:
How to check (via the preprocessor) if a C source file is being compiled as C++ code¿Cómo escribo un archivo de cabecera C que se puede usar en programas C++?

Estoy tratando de encontrar una macro estándar que probará si un archivo de cabecera se está compilando como C o como C++. El propósito de esto es que el encabezado se puede incluir por código C o C++, y debe comportarse de manera ligeramente diferente dependiendo de qué. Específicamente:

En C, necesito que esto sea el código:

extern size_t insert (const char*); 

En C++, necesito que esto sea el código:

extern "C" size_t insert (const char*); 

Además, hay una manera de evitar poniendo # ifdef alrededor de cada declaración en el encabezado?

+1

Puedo ser parcial, pero yo diría que esta pregunta también tiene que ver con extern. Como nunca antes había tenido conocimiento de la sintaxis "extern {...}", mi respuesta seleccionada es mucho más útil que la que se proporciona en el duplicado propuesto. Editaré la pregunta para mostrar esta diferencia. – Collin

+0

He dejado una x-ref a esta pregunta en el duplicado propuesto. Podría mejorar la distinción entre los dos por un título revisado como '¿Cómo definir condicionalmente' extern "C" 'o simplemente' extern' autodetectando el compilador C o C++? "O algo similar a esas líneas generales. –

+0

@JonathanLeffler He editado el título para reflejar lo que (creo) se está pidiendo realmente, como se ilustra en el ejemplo en el texto. Sin embargo, al buscar esto, se reveló un título duplicado: http://stackoverflow.com/ preguntas/8742534/including-c-header-in-c-file ... pero no contenido duplicado. –

Respuesta

27

Es normal encerrar los archivos de encabezado C de la siguiente manera para que puedan usarse en programas C++. Revisar sus archivos de cabecera del sistema, como stdio.h y es probable que vea esto:

#ifdef __cplusplus 
extern "C" { 
#endif 

... 

#ifdef __cplusplus 
} 
#endif 
15

La respuesta es usar el macro __cplusplus. En este caso, el enfoque más directo es:

extern 
#ifdef __cplusplus 
"C" 
#endif 
size_t insert (const char*); 

Esta macro forma parte del estándar C++.

+4

Y si desea hacer esto para funciones múltiples, la norma es '#ifdef __cplusplus extern" C "{# endif' ...' #ifdef __cplusplus} # endif'. – chris

+4

Otra posibilidad: '#ifdef __cplusplus' ...' #define EXTERN extern "C" '...' # else' ... '#define EXTERN extern' ...' # endif' (donde ...denota una nueva línea) –

+0

g ++ no le gusta #define EXTERN extern "C" que los vinos así: de error: se esperaba sin reservas-id antes constante de cadena – user1656671

7

Puede que le resulte razonable para definir tres macros para ayudar con esto:

#ifdef __cplusplus 
#define EXTERN_C_BEGIN extern "C" { 
#define EXTERN_C_END } 
#define EXTERN_C  extern "C" 
#else 
#define EXTERN_C_BEGIN /* Nothing */ 
#define EXTERN_C_END /* Nothing */ 
#define EXTERN_C  extern /* Or Nothing */ 
#endif /* __cplusplus */ 

Esto sería más útil en un encabezado estándar que se incluye en la mayoría de los lugares en su proyecto. Para una sola función, puede escribir:

EXTERN_C size_t insert(const char *name); 

para un grupo de funciones, es posible escribir:

EXTERN_C_BEGIN 

size_t other_insert(const char *name); 
size_t other_delete(const char *name); 
size_t other_update(const char *old_name, const char *new_name); 

EXTERN_C_END 

Es admisible incluir extern frente a las funciones individuales dentro de la EXTERN_C_BEGIN a EXTERN_C_END bloquear.

Cuestiones relacionadas