• 締切済み

関数ポインタについて

関数ポインタを使用する際に、 指定する先の関数でデフォルト引数が指定されている場合、 関数ポインタを用いて、その引数を省略して呼び出すことはできるのでしょうか? 以下例とします。 void function(int a = 10){}; typedef void (*test)(int a); test a = &function; a(); //このように呼び出したい

みんなの回答

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.5

ちょっと考えてみましょう。 void function0(int a){}; void function1(int a = 10){}; void function2(int a = 20){}; typedef void (*test)(int); test f ; としたときに f = &function0; f = &function1; f = &function2; いずれも正しいですね。では f(); としたら、何を引数に渡したらよいでしょう? void function(int a = 10) は、あくまで void function(int a) であって、 function() としたときに、プロトタイプから判断して funtion(10) としてコンパイルしてくれるだけです。

回答No.4

因みに、Visual C++ (Intel x86)の場合、呼出元が積んだスタック上の引数を開放するのは呼出先の責任(デフォルトはstdcall呼び出し規約)なので、呼ばれた先の関数は「引数が1つ積まれている筈だ」として、積まれていない引数を開放しようとして、スタックの操作を行う筈。 すると、引数がある筈の関数を引数を渡さずに呼んだ場合、呼び出し元に帰って来た時点でスタックがズレて、最悪、暴走します。 なので、functionの定義、test型のタイプ宣言で、呼び出し規約も含めて宣言し、そこだけ「呼出元が積んだスタック上の引数を開放するのは呼出元が行い、呼んだ先では操作しないように」と宣言する必要があります(つまり、functionの定義とtestのプロトタイプにcdecl呼び出し規約が必要) 呼び出し規約を理解しないままやると暴走するから「呼び出し規約って何?」ってレベルの場合は「キャストで無理矢理呼び出す」などという下手な考えはしない事。

回答No.3

因みに void function(int a = 10){}; typedef void (*test)(void); //testは引数なしで型宣言 test a = (test)(&function); //引数有りを引数無しに無理矢理にキャスト a(); //引数無しで呼び出す なら可能。 あと、C言語って、かなり柔軟性が高いから test a = (test)0x0445E000; //aに0x0445E000をセット a(); //0445e000番地を無理矢理に呼び出す とかって事も可能(0445e000番地のメモリにプログラムが無かったら何が起きるか判らない)

回答No.2

>a(); //このように呼び出したい 呼べない。呼ぶとエラーになる。 今のC++やC#の関数定義って「引数の個数や型も含めて定義される」から void function(int a) と void function(void) は「異なる定義になり、二重定義にはならない」のです。 事実、ある処理系では void function(int a) は、外部参照ラベルが __void_function_int としてリンケージエディタに渡され void function(void) は、外部参照ラベルが __void_function_void としてリンケージエディタに渡され、それぞれが異なる関数として実装されます。 なので a(); と書くと「そんな関数は知らん」って言われるか「引数の個数が違う」って言われる事になるでしょう。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

いいえ.