Cバイソンパーサーを使用するC++プロジェクトがあります。Cパーサーは、関数ポインターの構造体を使用して、生成がbisonによって削減されたときに適切なASTノードを作成する関数を呼び出します。
typedef void Node;
struct Actions {
Node *(*newIntLit)(int val);
Node *(*newAsgnExpr)(Node *left, Node *right);
/* ... */
};
さて、プロジェクトのC ++部分で、私はそれらのポインターを埋めます
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;
}
今、私がそれらを入れる唯一の理由extern "C"
は、Cの呼び出し規約を持たせたいからです。しかし、最適には、私は彼らの名前がまだ壊れていることを望みます。これらはCコードから名前で呼び出されることはないため、名前のマングリングは問題になりません。一部のアクションはのようerror
に呼び出され、C ++コールバック関数は他のモジュールとの名前の衝突を避けるために、次のような醜い名前を持っているため、それらをマングルすることで名前の競合を回避できます。
extern "C" {
void uglyNameError(char const *str) {
/* ... */
}
/* ... */
}
a.error = &uglyNameError;
関数型Cのリンケージを与えるだけで可能かどうか疑問に思いました
extern "C" void fty(char const *str);
namespace {
fty error; /* Declared! But i can i define it with that type!? */
}
何か案は?Standard-C++ソリューションを探しています。