0

私は書き込もうとしています:

typedef int foo();
...
foo bar
{
    return 1;
}

しかしerror C2206、typedefは関数宣言に使用できないということがあります。このエラーの原因は何ですか? foo barとしてコンパイルするだけでよいと思いますint bar()

4

2 に答える 2

3

この宣言:

typedef int foo();

完全に有効です。footype のエイリアスint()、つまり「引数を返さintず引数を取らない関数」として定義します。

(余談: C は(void)引数なしを示すために使用します。C++ は を使用します()。この回答の以前のバージョンは C の規則に基づいていました。)

関数型ではなく、関数へのポインター型に対して typedef を定義する方が一般的ですが、どちらも有効です。上記の typedef を指定すると、関数ポインター オブジェクトを次のように宣言できます。

foo *funcptr;

ただし、typedef を使用して関数を宣言または定義することはできません。言語で許可されている場合は、関数を次のように宣言できます。

foo func; /* would be equivalent to "int func(void);" *if* it were legal */

また:

foo func { return 42; }; /* would be equivalent to 
                            "int func(void) { return 42; }"
                            *if* it were legal */

これが便利な場合もあります。またはで定義された標準signal関数には、かなり複雑な宣言があります。<signal.h><csignal>

void (*signal(int sig, void (*func)(int)))(int);

typedefシグナル ハンドラの関数型に対してを定義できます。

typedef void (signal_handler)(int);

signal次のように宣言できます。

void (*signal(int sig, signal_handler *func);

ただし、その typedef を使用して独自のシグナル ハンドラーを宣言または定義することはできません。ただし、これを使用してシグナル ハンドラー関数へのポインターを宣言することはできます。

signal_handler *funcptr = my_handler;
signal(SIGINT, funcptr);

qsort()と で必要な関数ポインタ引数にも同じことが当てはまりますbsearch()

関数型の typedef を定義できるのに、それを関数の宣言または定義に使用できないのはなぜでしょうか?

深い理由はないと思います。言語がたまたまそれを許可していません。関数宣言の場合、1 つの問題は、

signal_handler foo;

オブジェクト宣言のように見えますが、代わりに関数を宣言します (別の場所で定義する必要があります)。そして、関数定義の typedef を許可します:

signal_handler foo { /* ... */ }

言語の文法を変更する必要があり、定義を見たときにパラメーターと戻り値の型を確認するのが難しくなります。また、関数定義は、宣言とは異なり、すべてのパラメーターに名前を付ける必要があるため、別のレベルの複雑さが追加されます。

しかし、本当の理由は、デニス・リッチーが C を設計したとき、C を考えていなかったか、価値があるとは考えていなかったからだと思います (そして、Stroustrup は C を変更する十分な理由を持っていませんでした。設計された C++)。

于 2013-10-13T21:51:07.677 に答える
1

関数ポインタ typedef の宣言は次のとおりです。

typedef int (*foo)();

また、関数宣言に括弧がありません

foo bar()
{
    return 1;
}

また1、正当な関数ポインタ値ではありません。

foo bar()
{
    return 1;  // this line is an error
}
于 2013-10-13T21:03:28.733 に答える