3

C++ では、main を関数ポインタで定義することは可能ですか? 例えば:

int f(int, char**) {
    return 0;
}

int (*main)(int, char**) = &f;

このコードは正しくコンパイルおよびリンクされますが、実行時にセグメンテーション エラーが発生します。関数ポインタの値をコードとして実行しようとしているからだと思います。

さらに、プレーンな C++ では不可能な場合は、gcc の非標準機能によって実現できます (おそらく、エクスポートされたシンボルの型を何らかの方法で変更します)。

最後に、gcc ディレクティブで実現できない場合、カスタム リンカー スクリプトで実現できますか?

4

8 に答える 8

6

C++ 標準の段落 3.6.1/1 は次のように述べています。

「プログラムには、プログラムの指定された開始である main と呼ばれるグローバル関数が含まれる必要があります」

これにより、ポインタ宣言が不正になります。

于 2013-01-17T12:38:33.017 に答える
4

あなたがやろうとしていることは、C ++では不可能だと思います。私が考えることができる最も簡単な解決策は、単にfあなたのメインを呼び出すことです:

int f(int, char**) {
    return 0;
}

int main(int argc, char** argv) {
  return f(argc, argv);
}

上記の解決策がうまくいかないシナリオも想像できません。

于 2013-01-17T12:37:54.617 に答える
4

なぜこれが必要なのか想像できませんが、いいえ、単純な C++ では絶対に不可能です。

このようなものが本当に必要な場合は、main の最初のコマンドとして呼び出す関数ポインターを使用してください。

于 2013-01-17T12:37:56.280 に答える
2

Linuxを使用していて、gccを使用している場合は、他の関数に対してmainとして宣言できます。alias

たとえば、以下のコードは機能します(少なくとも、gccでは、g ++ではテストされていません)。

int f(int argc, char* argv[]) {
    printf("hello world\n");
    return 0;
}

int main(int argc, char* argv[]) __attribute__ ((alias("f")));
于 2013-01-17T13:20:37.733 に答える
2

GCC では、オプションを使用してリンカにオプションを渡すことができ-Wlます。--entry次に、リンカーのオプションを使用して、最初に呼び出す関数を指定できます。

警告:これは期待どおりの動作をしません! プログラムのエントリ関数は、実際には関数ではなくmainランタイム環境をセットアップしてから関数を呼び出す別関数mainです。

于 2013-01-17T12:41:36.747 に答える
0

もう 1 つの「汚い」方法は、アセンブリ & をその関数の最初の命令として使用して偽の関数を作成することfです。

以下は、ターゲットのgcc特定のコードです。intel

asm(".globl main");           // main is not static
asm(".type main, @function"); // main is a 'function'
asm("main: jmp f");           // main starts here. jump to `f`

int g(){ //Some random function may be present in between "main" & "f"...
    puts("hello universe");
}

int f(int argc, char* argv[]) {
    int i;
    puts("hello world");
    printf("%d arguments given\n",argc - 1);
    for(i=0;i<argc;i++) puts (argv[i]);
    g();
    return 0;
}
于 2013-01-17T13:34:29.407 に答える
0

main は、C および C++ のキーワードであり、プログラム内で関数ポインター名として上書きされます。main は、実行のエントリ ポイントを定義します。したがって、プログラムにはその機能がなく、mainセグメンテーション違反で上書きされます。

于 2013-01-17T12:38:35.837 に答える