web-dev-qa-db-fra.com

C: Déclaration implicite de fonction

Je travaille sur une mission dans laquelle nous développons notre propre client RPC. Lors de la compilation de ma partie serveur, je reçois des avertissements pour les éléments suivants:

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

Je comprends que je recevrais généralement cet avertissement si je devais créer une fonction suivant mon principal, par exemple:

int main() {
    doSomething();
}

void doSomething() {
    ...
}

Dans le cas ci-dessus, il devrait se plaindre de la fonction que j'ai créée "doSomething".

Pourquoi alors mon compilateur se plaindrait-il qu'un appel système a été déclaré implicitement, alors qu'il apparaît dans une fonction qui a été déclarée avant le main? Vous trouverez ci-dessous la fonction dans laquelle l'appel système apparaît.

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*/
15
kubiej21

déclarations de fonctions implicites sont celles que le compilateur voit la première fois utilisées comme appel de fonction (par opposition à celles où un prototype ou une définition de fonction est vu en premier).

Les "appels système" ne font pas exception à cette règle, car les normes C ne font pas de distinction entre "fonctions ordinaires" et "appels système". Vous avez probablement oublié d'inclure l'en-tête correspondant fournissant le prototype (unistd.h).

3
Jens