__cplusplus macro para informar a g ++ sobre las declaraciones de encabezado C que no funcionan de manera extraña

Tengo una mezcla de código C C++. Todo compilado con g++. Dondequiera que tenga encabezados C, tengo el contenido del archivo de encabezado incluido dentro

#if defined(__cplusplus)
extern "C" {
#endif

y

#if defined(__cplusplus)
    extern "C" {
    #endif

Pero en un archivo de encabezado C obtengo errores de compilación g ++ donde accidentalmente usé un nombre de parámetro como plantilla, que obviamente es incorrecto y está en conflicto con la palabra clave c ++ plantilla.

Sé que puedo ir y cambiar el nombre de este parámetro, pero estoy pensando por qué es esto extern "C" declaración no funciona y por qué el archivo de encabezado se considera como código C++ y no C como pretendía.

g++ versión 4.1.1 Linux Red Hat Enterprise.

preguntado el 12 de junio de 12 a las 11:06

@Griwes - Lo sé. Pero código heredado, compilaciones heredadas. ¡Los cambios son lentos! -

@Griwes, todavía uso 3.x a veces :) -

@AmigableClarkKant, que no cambia la hecho que 4.1.1 es VIEJO. -

@Griwes, jaja, no. Creo que también tiene que ver con la edad. Se siente como si fuera ayer cambiando de 2.95 -

2 Respuestas

La extern "C" solo le dice al compilador (en realidad, el enlazador) que la manipulación de nombres de C++ no se aplica a las funciones declaradas en ese ámbito. No tiene nada que ver con la sintaxis o las palabras clave en sí.

Su mejor solución es cambiar el nombre de los símbolos en conflicto.

Respondido el 05 de diciembre de 12 a las 22:12

Es eso así. Yo estaba pensando. extern "C" le dice al enlazador que las siguientes declaraciones son código C. Que incluso las preguntas frecuentes de C++ parashift.com/c++-faq-lite/mixing-c-and-cpp.html#faq-32.3 parecía decir. - dorado

@goldenmean sí, y no hay contradicción aquí. Le dice que son funciones de C porque las funciones de C no tienen cambios de nombre en C++... - Luciano Grigore

Luchian tiene razón. Ver también Raymond Chen. - MSalters

@LuchianGrigore: En realidad le dice a la compiladorno, izquierda. La manipulación de nombres es un trabajo del compilador, no del enlazador. - Nawaz

@LuchianGrigore: Sí. Pero esa búsqueda no tiene nada que ver con extern "C". Todo lo que necesita el símbolo y dónde buscarlo. - Nawaz

Considerar:

extern "C" {
  namespace n
  {
    int& foo(bool b)
    {
      if (!b)
        throw std::invalid_argument("fail!");
      static int i = 0;
      return ++i;
    }
  }
}

Esta función tiene vinculación con el lenguaje C, pero usa referencias, espacios de nombres y excepciones, lo que espero que demuestre que extern "C" no cambia mágicamente el compilador para compilar C, solo le dice al compilador que use las convenciones de llamadas de C y las convenciones de nombres de símbolos para las funciones y variables con enlace de lenguaje C (lo que generalmente solo significa que deshabilita la manipulación de nombres y provoca declaraciones coincidentes en diferentes espacios de nombres para hacer referencia a la misma entidad).

Respondido el 12 de junio de 12 a las 13:06

Gracias de verdad. Al dar un 'contraejemplo', si puedo llamarlo así, es decir, la sintaxis del código C ++ dentro de un enlace C externo, aclara mi concepto muy bien. - dorado

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.