
以下のCソースでコンパイルすると、warning: passing arg 1 of `func_b' from incompatible pointer type
となります。
void (*p_func)() は、引数を省略しているので int として扱われるということでしょうか?
#include <stdio.h>
#include <stdlib.h>
void func_a( unsigned char x ){
printf( "x=%d\n", x ) ;
}
void func_b( void (*p_func)() ){
p_func( 1 ) ;
}
int main(){
func_b( func_a ) ;
return 0 ;
}
No.3ベストアンサー
- 回答日時:
まずは訂正から。
「関数や関数へのポインタを宣言するときに仮引数リストを空にすると、仮引数はないものとして扱われます。」と書きましたが、今の C の規格では
「関数を定義するときに仮引数リストを空にすると、仮引数はないものとして扱われます。これに対し、関数の(定義ではない)宣言や関数へのポインタの宣言(定義を含む)の場合には、引数の個数や型について一切情報が与えられないことを意味します。」くらいに解釈されます。将来的には変更されるはずですが。
今の場合 void (*p_func)() となっているので「p_func は void を返す関数で、その引数の個数や型は不明」ということになります。
ではなぜ unsigned char や unsigned short のときには warning が出るのに int や char * や long では出るのかという点に移るのですが、これはおそらく過去との互換性だと思います。ANSI/ISO C 以前、つまりいわゆる K&R の時代にはプロトタイプ宣言が存在しませんでした。この時代、char 及び short の引数は int に、また float の引数は double に自動的に変更されていました。つまり、関数の仮引数として char、short、float は許されていませんでした。
今考えている例では p_func に引数の情報が与えられていないため、その引数として char、short 及び float は許されず、その結果これらの型を持つ仮引数があるような関数を渡そうとすると warning が出るのだと思います。
No.2
- 回答日時:
関数や関数へのポインタを宣言するときに仮引数リストを空にすると、仮引数はないものとして扱われます。
つまり、今の場合 func_b の仮引数である p_func は void (*p_func)() と宣言されていますが、これは void (*p_func)(void) を意味します。
一方実引数である func_a の型は(型変換の結果) void (*)(unsigned char) になります。その結果 incompatible pointer type というメッセージが表示されることになります。
従って、func_b の宣言を
void func_b(void p_func(unsigned char)) または
void (func_b(void (*p_func)(unsigned char)) にすればメッセージは表示されなくなります。
func_b を呼出すときは
func_b(func_a); でも
func_b(&func_a); でもかまいません(f を関数名とすると、ほとんどの場合に f と &f は同じです)。
また、手元では void func_a(unsigned char x) を
void func_a(char *x) にしても同じメッセージが表示されましたよ。
この回答への補足
void (*p_func)()と仮引数を省略=intかと思っていたのですが、voidということでしょうか。
#shige_70さんも「intでない場合は省略するとWarningがでます」と。
文献は探してませんが何かありますでしょうか。
こちらは PC上でgccを使用していますが、void func_a(unsigned char x)のunsigned charのところを、void, int, unsigned long, char*などのポインタ全般、としてもWarningは出ません。一方、unsigned shortはWarningとなります。
No.1
- 回答日時:
6行目を
void func_b( void p_func(unsigned char) ){
としてください。
"()"は、関数『ポインタ』を意味します。それだけですでにポインタになっていますので、"*"をつけなくてもだいじょうぶです。
別につけても構わないのですが、その場合はその定義に合わせて10行目を
func_b( &func_a ) ;
とすることでWarningを抑止します。
また、関数の引数の型もおっしゃるとおりintでない場合は省略するとWarningがでます。
この回答への補足
void func_a( unsigned char x ){
printf( "x=%d\n", x ) ;
}
を
void func_a( char *x ){
printf( "x=%d\n", *x ) ;
}
とかにすると、Warningが出ないのはなぜでしょう。
void func_b( void (*p_func)() ){
の"()"がint扱いだとしたら、型があっていませんが?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
今、見られている記事はコレ!
-
弁護士が解説!あなたの声を行政に届ける「パブリックコメント」制度のすべて
社会に対する意見や不満、疑問。それを発信する場所は、SNSやブログ、そしてニュースサイトのコメント欄など多岐にわたる。教えて!gooでも「ヤフコメ民について」というタイトルのトピックがあり、この投稿の通り、...
-
弁護士が語る「合法と違法を分けるオンラインカジノのシンプルな線引き」
「お金を賭けたら違法です」ーーこう答えたのは富士見坂法律事務所の井上義之弁護士。オンラインカジノが違法となるかどうかの基準は、このように非常にシンプルである。しかし2025年にはいって、違法賭博事件が相次...
-
釣りと密漁の違いは?知らなかったでは済まされない?事前にできることは?
知らなかったでは済まされないのが法律の世界であるが、全てを知ってから何かをするには少々手間がかかるし、最悪始めることすらできずに終わってしまうこともあり得る。教えてgooでも「釣りと密漁の境目はどこです...
-
カスハラとクレームの違いは?カスハラの法的責任は?企業がとるべき対応は?
東京都が、客からの迷惑行為などを称した「カスタマーハラスメント」、いわゆる「カスハラ」の防止を目的とした条例を、全国で初めて成立させた。条例に罰則はなく、2025年4月1日から施行される。 この動きは自治体...
-
なぜ批判コメントをするの?その心理と向き合い方をカウンセラーにきいた!
今や生活に必要不可欠となったインターネット。手軽に情報を得られるだけでなく、ネットを介したコミュニケーションも一般的となった。それと同時に顕在化しているのが、他者に対する辛らつな意見だ。ネットニュース...
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
多重定義が起きている?--lnk20...
-
静的でないメンバ関数の呼び出...
-
既定のコンストラクタがありま...
-
C# Controls.Addで動的に配置し...
-
C++にてtemplateで受け取った任...
-
C言語 プロトタイプ宣言
-
C# KeyDownイベントでショート...
-
戻り値を返す関数の前に(void)...
-
const_castのつかいどころを教...
-
void*型の配列について
-
(void)0 はどんな意味ですか
-
typedef unsigned int UINT;が...
-
【gcc・cygwin】multiple defin...
-
CTabCtrl:TABインデックス単位...
-
Arduinoでの圧電スピーカーとタ...
-
gcc: incompatible pointer type
-
関数ポインタについて
-
stddef.hって何?
-
別ソースファイル、同クラス名...
-
コンパイルエラー: LNK2001
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
静的でないメンバ関数の呼び出...
-
既定のコンストラクタがありま...
-
C++にてtemplateで受け取った任...
-
多重定義が起きている?--lnk20...
-
【gcc・cygwin】multiple defin...
-
const_castのつかいどころを教...
-
戻り値を返す関数の前に(void)...
-
C言語 ① 5秒間 1秒間隔で点滅を...
-
C# Controls.Addで動的に配置し...
-
C#でテンキーの操作は可能でし...
-
int main()、void main()、void...
-
C# KeyDownイベントでショート...
-
gcc: incompatible pointer type
-
Notepad++の関数リスト表示の変...
-
(void)0 はどんな意味ですか
-
VC++でGetKeyboardStateがうま...
-
関数ポインタについて
-
void main()って誰が最初?:AN...
-
演算子のオーバーロードでコン...
-
この式の意味
おすすめ情報