エラー「invalid conversion from `void (*)()' to `void (*)(int)'」

このQ&Aのポイント
  • RedHat9上でコンパイルしている「鬼ごっこのプログラム」のエラー
  • 134行目の「signal(SIGINT, die);」でエラーが発生
  • 「void (*)()' を `void (*)(int)' に変換できないエラー
回答を見る
  • ベストアンサー

エラー「invalid conversion from `void (*)()' to `void (*)(int)'」

皆様、よろしくお願いしたします。RedHat9上で 次のような「鬼ごっこのプログラム」server.cをコンパイルしています。 $ g++ -o server server.c server.c: function 内の `void session_init(int, char, int, int, char, int, int)': server.c:134: invalid conversion from `void (*)()' to `void (*)(int)' というエラーが出てしまいます。 134行というと 「 signal(SIGINT, die);」 なのですが何が間違っているんでしょうか?

質問者が選んだベストアンサー

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

die の宣言を void die(int sig); にしたのであれば, session_loop の中で die を呼出すときにも引数は必要ですよ. また, 最後の die の定義のところでも引数を取るようにしていますよね? ←念の為.

YYoshikawa
質問者

お礼

有難うございます。

YYoshikawa
質問者

補足

お手数をお掛けしています。 > die の宣言を > void die(int sig); > にしたのであれば, session_loop の中で die を呼出すときにも引数は必要ですよ. > また, 最後の die の定義のところでも引数を取るようにしていますよね? ←念の為. $g++ -o server server.c server.c: function 内の `void session_init(int, char, int, int, char, int, int)': server.c:134: void の値が本来の意味通りに無視されませんでした となってしまいました。 何か勘違いしてますでしょうか?? #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <sys/types.h> #include <curses.h> #include <signal.h> #include <unistd.h> #define BUF_LEN 20 #define MIN_X 1 #define MIN_Y 1 #define MAX_X 60 #define MAX_Y 20 /* 移動キーの割り当て */ #define NORTH 'k' #define SOUTH 'j' #define EAST 'l' #define WEST 'h' #define QUIT 'q' #define PORT (in_port_t)50001 #define HOSTNAME_LENGTH 64 int setup_server(in_port_t port) /* 戻り値 ソケットのディスクリプタ */ /* port 接続先のポート番号 */ { struct sockaddr_in me; /* 自分のソケットのアドレス */ int soc_waiting; /* 接続待ちのソケット */ int soc; /* 通信に使うソケット */ /* 自分のアドレスを sockaddr_in 構造体に設定 */ memset((char *)&me, 0, sizeof(me)); me.sin_family = AF_INET; me.sin_addr.s_addr = htonl(INADDR_ANY); me.sin_port = htons(port); /* IPv4 でストリーム型のソケットの作成 */ if ((soc_waiting = socket(AF_INET,SOCK_STREAM,0)) < 0 ){ perror("socket"); return -1; } /* ソケットに自分のアドレスを設定 */ if (bind(soc_waiting,(struct sockaddr *)&me,sizeof(me)) == -1){ perror("bind"); return -1; } /* ソケットで接続待ちの設定 */ listen(soc_waiting,1); fprintf(stderr,"successfully bound, now waiting.\n"); /* 接続要求があるまでブロック */ soc = accept(soc_waiting, NULL, NULL); /* 接続待ちに使ったソケットを閉じる */ close(soc_waiting); /* 通信に使うソケットのディスクリプタを返す */ return soc; } char * chop_newline(char *str, int len) /* 戻り値 与えられた文字列の先頭アドレス */ /* str 改行文字で終わっているかも知れない文字列 */ /* len 処理の制限 */ { int n = strlen(str); /* 与えられた文字列の長さ */ /* 末尾が改行文字なら削る */ if(n<len &&str[n-1]=='\n'){ str[n-1]='\0'; } /* 先頭番地を返す */ return str; } /* プライベート変数 */ static int session_soc; /* socket */ static fd_set mask; /* fd mask */ static int width; /* width of the mask */ static char my_char, peer_char; /* character */ typedef struct{ int x,y; /* current position */ char look; /* character */ } PLAYER; static PLAYER me, peer; /* 自分と相手の状態を保持する変数 */ static char buf[BUF_LEN]; /* 送受信兼用バッファ */ static WINDOW *win; /* 表示用ウィンドウ */ /* session モジュールにプライベートな関数 */ static void hide(PLAYER *who); static void show(PLAYER *who); static int update(PLAYER *who, int c); static int interpret(PLAYER *who); static void die(int);

その他の回答 (1)

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

signal の使い方を見ればすぐにわかりますが, void die() ではなく void die(int sig) としなければなりません.

YYoshikawa
質問者

お礼

有難うございます。

YYoshikawa
質問者

補足

ご回答ありがとうございます。 > signal の使い方を見ればすぐにわかりますが, > void die() > ではなく > void die(int sig) > としなければなりません. static void die(int sig); /* session モジュールの初期化 */ void session_init(int soc, char mc, int mx, int my, char pc, int px, int py) /* soc ソケットのディスクリプタ */ /* mc 自分の表示用の文字 */ /* mx 自分の初期x座標 */ /* my 自分の初期y座標 */ /* pc 相手の表示用の文字 */ /* px 相手の初期x座標 */ /* py 相手の初期y座標 */ { /* 初期データの設定 */ session_soc = soc; width = soc + 1; FD_ZERO(&mask); FD_SET(0, &mask); FD_SET(session_soc, &mask); me.look = mc; peer.look = pc; me.x = mx; me.y = my; peer.x = px; peer.y = py; /* curses の初期化 */ initscr(); signal(SIGINT, die);  という具合に 「static void die;」 ↓ 「static void die(int sig);」 書換えましたら $ g++ -o server server.c server.c: function 内の `void session_loop()': server.c:106: too few arguments to function `void die(int)' server.c:186: ファイルのこの位置 server.c: トップレベル: server.c:106: `void die(int)' が使われましたが未定義です となっていました。 勘違いしてますでしょうか? #include <signal.h> typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t sighandler); というのを見つけました。 int型引数・void型返値の関数へのポインタをsighandler_t型に定義。 signal関数を int型変数signum と sighandler_t型変数sighandler の2つを引数にとるsighandler_t型返値の関数に定義。 という意味ですよね?

関連するQ&A

  • (続)エラー「invalid conversion from `void (*)()' to `void (*)(int)'」

    お手数をお掛けしています。 > die の宣言を > void die(int sig); > にしたのであれば, session_loop の中で die を呼出すときにも引数は必要ですよ. > また, 最後の die の定義のところでも引数を取るようにしていますよね? ←念の為. えーと、下記のように static void die(int); : (中略) : signal(SIGINT, die(1)); : (中略) : /* 端末属性を復旧して終わる */ die(1); } : (中略) : static void die(int) { endwin(); /* 端末属性の復旧 */ exit(0); } としてみたのですが $g++ -o server server.c server.c: function 内の `void session_init(int, char, int, int, char, int, int)': server.c:134: void の値が本来の意味通りに無視されませんでした となってしまいました。 何か勘違いしてますでしょうか??

  • エラーがとれません 助けてください

    エラーがとれません 助けてください http://cs.fit.edu/~mmahoney/dist/eval4.cpp をコンパイルすると eval4.cpp: In member function ‘bool Attack::read(FILE*)’: eval4.cpp:105: error: ‘strlen’ was not declared in this scope eval4.cpp:114: error: ‘strchr’ was not declared in this scope eval4.cpp: In function ‘int main(int, char**)’: eval4.cpp:132: warning: deprecated conversion from string constant to ‘char*’ eval4.cpp:133: warning: deprecated conversion from string constant to ‘char*’ eval4.cpp:134: warning: deprecated conversion from string constant to ‘char*’ eval4.cpp:183: error: ‘strlen’ was not declared in this scope のようなエラーがでてしまいます。 Ubuntuのg++でコンパイルしています。 なにがまずいのでしょうか?

  • 関数の引数をvoid*でキャストする

    最近見かけたCのプログラムで、関数の引数の型は void* なのですが、その関数を使うときに 引数をvoid*でキャストしていました。 例えば、 func ( (void*) p ); こういうことです。 私の知っている知識では、 void* と 任意の型のポインタは キャストなしに相互に代入可能です。 関数の引数でも、キャストは要らないものだと思っていました。 そうすると、引数を void* でキャストするのは無意味だと思うのですが、・・・ 違うのでしょうか。処理系によるとか。 逆に、関数の引数の型がchar*などで、渡すものが void* のときはどうなのでしょうか。 下のプログラムは、関数byte_orderの引数の型はvoid*ですが、int型へのポインタ( &a )を設定しています。私の環境では、コンパイルエラーも警告もないし、動作も正常です。 #include <stdio.h> #include <string.h> void byte_order(void *vp) { char char_array[4]; strncpy(char_array, vp, 4); printf("出力します:%x %x %x %x\n", char_array[0], char_array[1], char_array[2], char_array[3]); } int main(void) { int a = 0x12345678; byte_order(&a); return 0; } このプログラムは単なる一例であって、質問はバイトオーダに関するものではありません。 また、C言語の質問であって、C++ではありません。

  • int型とchar型について

    C言語初心者です。 よろしくお願いします。 ◎1----------------------- #include<stdio.h> int main(void) { int ss[4]="789"; printf("%c\n",ss[0]); return 0; } --------------------------- ◎2----------------------- #include<stdio.h> int main(void) { int *p; p="789"; printf("%c\n",*p); return 0; } --------------------------- ◎1、◎2の2つのプログラムについて疑問があります。 ◎1の「int ss[4]="789";」と◎2の「int *p;」のintの部分は今まで、何の疑問も抱かず、「char」として入力していました。 そこでchar型は1バイトの整数、int型は4バイトの整数ということで容量が違うだけで、intとしても大丈夫だろうと思ったのですが、 ◎1では、「'initializing' : 'char [4]' から 'int [4]' に変換することはできません。」とエラーが出て、◎2では「'char [4]' から 'int *' に変換することはできません。」とエラーが出ます。 intは文字列は扱えないということなのでしょうか? 以上intだと実行できない理由がわかりません。 初歩的なことですいませんが、教えていただけると嬉しいです。

  • void型へのポインタ

    というのがC言語にありますよね? このvoid型へのポインタというのは、 どのようにイメージすればいいのでしょうか? 例えばchar型へのポインタなら、 指している領域は 1バイトの領域ですよね? ではvoid型は? また malloc関数を 使って char *p; p=(char *)malloc(1000); とするとでchar型にキャストしているから、 1個1バイト分の領域が1000個用意して、 先頭アドレスをpに格納するのですよね? では、 int *q; q=(int *)malloc(1000); としたら、用意されるのは、int型にキャストしているから 1個2バイト分の領域が500個用意されるのでしょうか? お願いします。

  • コンパイルエラー invalid operands to binary

    自己啓発で入力文字列をBASE64デコードする関数を作っているのですが、L20~L23(a[0] = strchr(b64, p[0]) - b64;)でコンパイルエラーinvalid operands to binaryが発生して色々試行錯誤しているのですが、どうしてもエラーがとれません。 ソースをここに書くのは大変恐縮なのですが、原因がわかる方がいらっしゃいましたら、教えていただけないでしょうか? char *Base64n(unsigned char *buf, size_t length, size_t *outlen) { const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrst         uvwxyz0123456789+/="; unsigned char *p; unsigned char *q; unsigned char a[4]; char *RtnBuf; int j=0; int cnt; RtnBuf = (char *)malloc(length+1); memset(RtnBuf, 0, length+1); p = (unsigned char*)buf; q = (unsigned char*)RtnBuf; cnt = 0; while(*p != 0) { a[0] = a[1] = a[2] = a[3] = 0; a[0] = strchr(b64, p[0]) - b64; a[1] = strchr(b64, p[1]) - b64; a[2] = strchr(b64, p[2]) - b64; a[3] = strchr(b64, p[3]) - b64; q[0] = ((a[0] << 2) | (a[1] >> 4)) & 0xff; cnt++; if (p[2] != '=') { q[1] = ((a[1] << 4) | (a[2] >> 2)) &0xff; cnt++; } if (p[3] != '=') { q[2] = ((a[2] << 6) | a[3]) & 0xff; cnt++; } p += 4; q += 3; } *outlen = cnt; return(RtnBuf); } コンパイルはRed Hatでgccを使ってコンパイルしています。 引数は第1引数がデコード対象の文字列、第2引数がデコード対象文字列長、第3引数がデコード後の文字列長で、戻り値がデコード後の文字列です。

  • signal関数の使い方

    標準関数のsignal()関数についてですが void (*signal(int sig, void (*func)(int)))(int); 関数の形式からしてよくわかりません。 僕のイメージでは関数のポインタというと void (*func)(int,int) という感じですが上の場合 void (*func(int,int))(int) /*引数は仮にint型*/ という形式になってますよね。末尾の(int)は引数のはずですがどこの引数になっているのかよくわかりません。 しかも関数の使用例などをみると signal(SIGINT, func); という形で使っており末尾の(int)がどこにいったのかさっぱりわかりません。 よろしくお願いします。

  • C++(というよりC)で文字を置換

    現在じゃんけんさせるプログラムを作っています。その中で 0→ぐー 1→ちょき 2→パー のように変換してreturnさせる関数を作りたいのです。 現状作ったファイルをコンパイルすると VisualStudioだと エラー 1 error C2440: 'return' : 'char [20]' から 'int' に変換できません。 27 1 じゃんけん・改 2 IntelliSense: 戻り値の型が関数型と一致していません 27 9 じゃんけん・改 g++だと In function 'int Replacement(int)': 19:20: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings] char *Replaced = "パー"; ^ 22:20: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings] char *Replaced = "ちょき"; ^ 25:20: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings] char *Replaced = "ぐー"; ^ 27:9: error: invalid conversion from 'char*' to 'int' [-fpermissive] return Replaced; ^ 17:7: warning: address of local variable 'Replaced' returned [-Wreturn-local-addr] char Replaced[20] = { 0 }; ^ In function 'int main()': 60:27: error: 'scanf_s' was not declared in this scope scanf_s("%d", &player_c); とエラーやら警告がでます。g++のscanf_sのエラーはscanfにすればいいので気にしないとして、どうすれば目的の関数が作れますか? [ソース抜粋] int Replacement(int ver){ char Replaced[20] = { 0 }; if (ver == 2){ char *Replaced = "パー"; } else if (ver == 1){ char *Replaced = "ちょき"; } else{ char *Replaced = "ぐー"; } return Replaced; /*switch (ver){ case 2: char *Replaced = "パー"; return Replaced; break; case 1: char *Replaced = "ちょき"; break; default: char *Replaced = "ぐー"; break; }*/ } void Which_is_Winner(int player_c,int cpu_c, int Judge_Which_is_Winner){ printf("じゃんけん・・・・・・ポンっ!\n"); printf("あなた:%s\nCPU:%s\nじゃんけん", Replacement(player_c), Replacement(cpu_c));//それぞれの手を表示 if (player_c == Judge_Which_is_Winner){ printf("あなたの勝ちです!\n"); } else { printf("cpuの勝ちです!\n"); } }

  • コンパイルエラー

    以下のようなソースファイルをコンパイルしたらコンパイルに失敗してしまいました。エラーは『Cls1はabstractで宣言する必要があります。show(int)をCls1で定義しません』と出ます。これはどういうことでしょうか。 interface Int1 { int x=100; void Show(int y); } class Cls1 implements Int1 { public void show(int x) { System.out.println(x); } } class Test12 { public static void main(String args[]) { Cls1 c; c = new Cls1(); c.show(200); } }

    • ベストアンサー
    • Java
  • C言語でのコンパイルエラー

    初心者です。 非常に基本的な質問かもしれませんが、 ご回答いただけたらうれしいです。 void test1(unsigned char* data) { } void test2(unsigned char** data) { } int main(void) { unsigned char data1[6]; unsigned char data2[6][6]; test1(data1); test2(data2); } としてtest1はうまくいくのに、 test2はコンパイルエラーになります。 どっちもポインタになると思うのですが…。 また、unsigned char data2[6][6]を 他の関数の引数とする場合は どうすればよろしいのでしょうか? 宜しくお願いいたします。

専門家に質問してみよう