Tengo un proyecto de C++ que utiliza un analizador de bisontes C. El analizador C utiliza una estructura de punteros de función para llamar a funciones que crean nodos AST adecuadas cuando las producciones son reducidas por el bisonte:C funciones de devolución de llamada definidas en un espacio de nombre sin nombre?
typedef void Node;
struct Actions {
Node *(*newIntLit)(int val);
Node *(*newAsgnExpr)(Node *left, Node *right);
/* ... */
};
Ahora, en la parte C++ del proyecto, i llenar esos punteros
class AstNode {
/* ... */
};
class IntLit : public AstNode {
/* ... */
};
extern "C" {
Node *newIntLit(int val) {
return (Node*)new IntLit(val);
}
/* ... */
}
Actions createActions() {
Actions a;
a.newIntLit = &newIntLit;
/* ... */
return a;
}
Ahora, la única razón por la que los incluyo en extern "C"
es porque quiero que tengan convenciones de llamadas en C. Pero de manera óptima, me gustaría que sus nombres sigan mutilados. Nunca se les llama por nombre desde el código C, por lo que el cambio de nombre no es un problema. Tenerlos destrozados evitará conflictos de nombres, ya que algunas acciones se llaman como error
, y la función de devolución de llamada de C++ tiene nombres feos como los siguientes solo para evitar conflictos de nombres con otros módulos.
extern "C" {
void uglyNameError(char const *str) {
/* ... */
}
/* ... */
}
a.error = &uglyNameError;
me preguntaban si podría ser posible con sólo dar el tipo de función C vinculación
extern "C" void fty(char const *str);
namespace {
fty error; /* Declared! But i can i define it with that type!? */
}
¿Alguna idea? Estoy buscando soluciones Standard-C++.
¿No se puede compilar la salida de Bison como código C++, evitando así el problema por completo? –
@Konrad, mi colega dijo que no es agradable trabajar con el modo binario C++, por lo que hacemos esa parte con C puro y la abstraemos, de modo que junto con el escáner constituye una biblioteca C pura. –