こんにちは。フォローありがとうございます。

On Mon, 24 Nov 2003 13:47:44 +0900
takao@hirata.nuee.nagoya-u.ac.jp (Takao Ono) wrote:

> どのような構文に対する例外だとお考えでしょうか?

普通のポインタの宣言構文に対して、
関数へのポインタの宣言構文が例外のように感じました。
(例外というよりは別物であるという認識なのでしょうか。)

僕が最初に <20031122173333.F99C.INGRAM@os.rim.or.jp> の記事で書いた
typedefはあまり関係なかったかもしれません。
そもそもなんでこのような疑問を抱いたかというと
あるプログラムの中で
typedef int (*fp)(int);
のような、関数へのポインタの型名を作成してる部分を見て、
このようなtypedefの使い方を知らなかったため調べ始めた中で出てきたもの
なのですが、、、

typedefの使い方としては、
typedef 型名 新型名;
というのがまず基本にあると思います。

この程度ならシンプルでわかりやすいのですが、
# というかこれだけの機能であれば#defineで事足りてしまいますが

上の、「型名」と同義語である「新型名」を作成するという認識があったとき
typedef int (*fp)(int);
のような記述で混乱を生じてしまいました。

本当は最初、
typedef int (*fp)(int);
という記述は
# intを1つ引数にもちintを返す関数へのポインタ型名fpを作成するという
イメージで、
typedef int(*)(int) fp; 
とか、
typedef int *int_ptr;
のような記述にならうなら、
typedef int()(int) *fp;
見たいな感じで記述したい気持ちでした。(ちょっと無理やりですが。)

いろいろ考えたのですが、次のように考えると理解も苦しくないのではないか
と勝手に結論付けてしまいました。(ぜんぜん間違っているかもしれませんが。)
関数へのポインタは、
普通のポインタと同じような「変数」的なイメージではなく、
関数のスタート位置(アドレス)の変更が可能な関数プロトタイプ宣言の
イメージである。
# スタート位置が変更可能であるため、関数定義も存在しない。
# また左辺値になり得る

普通の関数プロトタイプ宣言と
スタート位置(アドレス)変更可能な関数のプロトタイプ宣言
の記述の違いは、関数名の前に「*」をつけるかつけないかで
区別する。(演算子優先順位の関係で“()”が必要)

このプロトタイプ宣言の前にtypedefをつけると、、、?
ここでよくわからなくなってしまいました。

いろいろ調べたのですが、
typedef int F(int);
なんてのも構文的には正しいようです。しかもこれは関数定義扱いになるようです。

もうすでに別の話になってしまいますが、
具体的な、このtypedefの用例なんかも知りたいのですが、
文献等あれば教えていただけませんでしょうか。