18

私は、独自の RPC クライアントを開発する課題に取り組んでいます。サーバー部分をコンパイルすると、次の警告が表示されます。

implicit declaration of function 'read'
implicit declaration of function 'write'

メインの関数に続いて関数を作成すると、通常、この警告が表示されることを理解しています。例:

int main() {
    doSomething();
}

void doSomething() {
    ...
}

上記の場合、「doSomething」を作成した関数について文句を言う必要があります。

では、システム コールがメインの前に宣言された関数内にあるときに、システム コールが暗黙的に宣言されたとコンパイラが文句を言うのはなぜでしょうか? 以下は、システムコールが登場する関数です。

void Open(int connfd) {
/*Get message size*/
unsigned char temp[4] = { 0 };
int n = read(connfd, temp, 4);
if(n < 0) {/*On error*/
    perror("Read error");
    exit(1);
}/*End if*/
unsigned int msgSize = temp[0] +
    (temp[1] * 256) + 
    (temp[2] * 256 * 2) + 
    (temp[3] * 256 * 3);
printf("msgSize = %d\n", msgSize);

/*Allocate memory for message*/
char * msg = malloc(msgSize);
if(msg == NULL) {
    perror("Allocation error");
    exit(1);
}/*End if*/
msg = memset(msg, 0, msgSize);

/*Read entire message from client*/
n = read(connfd, msg, msgSize);
if(n < 0) {/*On error*/
    perror("Read error");
    exit(1);
}/*End if*/

/*Extract pathname from message - NULL terminated*/
char * pathname = malloc(strlen(msg) + 1);
if(pathname == NULL) {
    perror("Allocation error");
    exit(1);
}/*End if*/
pathname = memset(pathname, 0, strlen(msg) + 1);
pathname = memcpy(pathname, msg, strlen(msg));

/*Extract flags from message*/
int i;
for(i = 0; i < sizeof(int); i++) {
    temp[i] = msg[strlen(pathname) + 1 + i];
}/*End for i*/
unsigned int flags = temp[0] + 
    (temp[1] * 256) + 
    (temp[2] * 256 * 2) + 
    (temp[3] * 256 * 3);

/*Extract mode from message*/
for(i = 0; i < sizeof(mode_t); i++) {
    temp[i] = msg[strlen(pathname) + 1 + sizeof(int) + 1 + i];
}/*End for i*/
mode_t mode = temp[0] + 
    (temp[1] * 256) + 
    (temp[2] * 256 * 2) + 
    (temp[3] * 256 * 3);

free(msg);/*Free msg since it is no longer needed*/

/*Open pathname*/
umask(0);
int fd = open(pathname, flags, mode);

free(pathname);/*Free pathname since it is no longer needed*/

/*Prepare response*/
char * response = malloc(sizeof(int) * 2);
if(response == NULL) {
    perror("Allocation error");
    exit(1);
}/*End if*/
response = memset(response, 0, sizeof(int) * 2);

/*Build return message*/
memcpy(&response[0], &fd, sizeof(fd));
memcpy(&response[4], &errno, sizeof(fd));

/*Can't guarante socket will accept all we try to write, cope*/
int num, put;
int left = sizeof(int) * 2; put = 0;
while(left > 0) {
    if((num = write(connfd, response + put, left)) < 0) {
        perror("inet_wstream: write");
        exit(1);
    } else {
        left -= num;
        put += num;
    }/*End else*/
}/*End while*/

free(response);/*Free response since it is no longer needed*/

return;
}/*End Open*/
4

2 に答える 2

54

#include <unistd.h>プログラムに include ディレクティブを追加します。

readおよびwrite関数が宣言されてunistd.hおり、関数を呼び出す前に関数の宣言が必要です。

于 2013-04-23T20:48:03.320 に答える
3

暗黙的な関数宣言は、コンパイラが関数呼び出しとして初めて使用されるものです (プロトタイプまたは関数定義が最初に見られるものとは対照的に)。

C標準では「通常の関数」と「システムコール」を区別していないため、「システムコール」もこのルールの例外ではありません。プロトタイプ ( ) を提供する関連ヘッダーを含めるのを忘れている可能性がありますunistd.h

于 2013-04-23T20:56:07.393 に答える