void (* pFunc_pcInt) (int const *) = nullptr ;
void (* pFunc_pInt) (int *) = reinterpret_cast< void (*) (int *) >(pFunc_pcInt) ;
このような変換は未定義の動作につながりますか? standard (ワーキングドラフト、強調鉱山)からようパラメータの追加の修飾を除く、同じシグネチャを持つポインタから関数へのポインタへの変換
void (* pFunc_pcInt) (int const *) = nullptr ;
void (* pFunc_pInt) (int *) = reinterpret_cast< void (*) (int *) >(pFunc_pcInt) ;
このような変換は未定義の動作につながりますか? standard (ワーキングドラフト、強調鉱山)からようパラメータの追加の修飾を除く、同じシグネチャを持つポインタから関数へのポインタへの変換
:
関数ポインタは、明示的に異なるタイプの関数ポインタに変換することができます。 [注意:関数の定義で使用されている型と同じではない関数型([dcl.fct])へのポインタによる関数の呼び出しの効果は、定義されていません。 - 終了ノート] [...]
そしてもちろん、void(int const *)
とvoid(int *)
は異なるタイプです。同様の
何かが最も知らonline reference(強調鉱山)のいずれかから来る:
関数への任意のポインタが異なる関数型へのポインタに変換することができます。 異なる関数型へのポインタを介して関数を呼び出すことは定義されていません。しかし、このようなポインタを元の関数型へのポインタに変換すると、元の関数へのポインタが返されます。
特定のケースでは、それほど重要ではありません。nullptr
を関数ポインタに割り当てているためです。いずれにしても、それを呼び出すとエラーになります。
有効な関数ポインタをpFunc_pcInt
に割り当てた場合、変換されたポインタpFunc_pInt
によってUBが呼び出されます。
私は非常に無関係な段落のどこかに隠されている例外のようなものを考えましたが、それはそうではないようです。 –
@GreenTree:多くのCコンパイラは、特に組み込み関数やシステムプログラミングを目的としたもので、呼び出される関数が必要とする方法で呼び出しコードが設定されている場合に、暗黙的に動作を定義する方法で呼び出し規約を明示的に文書化しています。名前の変更やその他の問題のために、関数とポインタが 'extern" C "{...}"として宣言されている場合を除いて、呼び出し規約はC++では未定義になりがちです。 – supercat
@supercat、 "呼び出し規約はC++で不特定になる可能性が高い"ということはどういう意味ですか?そして召集慣習は名前の絡み合いにどのように関係していますか? –