皆様、よろしくお願いしたします。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);」
なのですが何が間違っているんでしょうか?
No.2ベストアンサー
- 回答日時:
die の宣言を
void die(int sig);
にしたのであれば, session_loop の中で die を呼出すときにも引数は必要ですよ.
また, 最後の die の定義のところでも引数を取るようにしていますよね? ←念の為.
この回答への補足
お手数をお掛けしています。
> 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);
No.1
- 回答日時:
signal の使い方を見ればすぐにわかりますが,
void die()
ではなく
void die(int sig)
としなければなりません.
この回答への補足
ご回答ありがとうございます。
> 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が見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
天使と悪魔選手権
悪魔がこんなささやきをしていたら、天使のあなたはなんと言って止めますか?
-
フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
あなたが普段思っている「これまだ誰も言ってなかったけど共感されるだろうな」というあるあるを教えてください
-
映画のエンドロール観る派?観ない派?
映画が終わった後、すぐに席を立って帰る方もちらほら見かけます。皆さんはエンドロールの最後まで観ていきますか?
-
海外旅行から帰ってきたら、まず何を食べる?
帰国して1番食べたくなるもの、食べたくなるだろうなと思うもの、皆さんはありますか?
-
天使と悪魔選手権
悪魔がこんなささやきをしていたら、天使のあなたはなんと言って止めますか?
-
<unistd.h>をVisualStudioでつかえるようにする
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
long型の定数の末尾にLを付ける...
-
C++のfor文について
-
DWORDの実際の型は何でしょうか
-
VB6から参照可能なDLLの作成
-
visualstudio C# テキストボッ...
-
2重定義って??
-
main.c:7:43: warning: implici...
-
typedef enumの使い方を教えて...
-
enumについて
-
unsigned *という宣言について
-
配列を用いない最大値の求め方
-
GCCで暗黙の型変換の警告を出し...
-
構造体の要素すべてに対する四...
-
関数の実体定義にヘッダファイ...
-
intとINTの違いは?
-
64bit → 32bit型へのキャスト
-
void func( void )について
-
クラスのファイル分割について
-
VC6でlong longでエラー?
-
C++ クラスをメンバにもつクラ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
DWORDの実際の型は何でしょうか
-
visualstudio C# テキストボッ...
-
C++のfor文について
-
2重定義って??
-
long型の定数の末尾にLを付ける...
-
typedef enumの使い方を教えて...
-
main.c:7:43: warning: implici...
-
C++でboolにintの値を代入する...
-
構造体の要素すべてに対する四...
-
intとINTの違いは?
-
ハンドルされていない例外が発...
-
DDVによるメッセージの変更
-
変数の型を定義しなかった場合...
-
【#define】 defineで定義した...
-
C++ クラスをメンバにもつクラ...
-
構造体の宣言でエラーが出ます。
-
プログラムの中で別のmainを呼...
-
void func( void )について
-
エラー「invalid conversion fr...
-
関数の実体定義にヘッダファイ...
おすすめ情報