types en conflit erreur en C

Pour le code C suivant (pour permuter deux nombres), je reçois le message d’erreur “types en conflit” pour la fonction de swap .

 #include  #include  void main() { int a,b; printf("enter the numbers to be swapped"); scanf("%d%d",&a,&b); printf("before swap"); printf("a=%d,b=%d",a,b); swap(&a,&b,sizeof(int)); printf("after swap"); printf("a=%d,b=%d",a,b); getch(); } void swap(void *p1,void *p2,int size) { char buffer[size]; memcpy(buffer,p1,size); memcpy(p1,p2,size); memcpy(p2,buffer,size); return(0); } 

Quelqu’un peut-il expliquer pourquoi cette erreur se produit?
quelle est la solution pour cela?

Le problème est que l’ swap n’a pas été déclaré avant son utilisation. Ainsi, une “signature par défaut” lui est atsortingbuée, qui, dans ce cas, ne correspondra pas à sa signature réelle. Citer Andrey T :

Les arguments sont transmis à travers un ensemble de conversions ssortingctement définies. int * pointeurs int * seront passés en tant que pointeurs int * , par exemple. En d’autres termes, les types de parameters sont temporairement “déduits” des types d’arguments. Seul le type de retour est supposé être int .

En plus de cela, votre code produit une foule d’autres avertissements. Si vous utilisez gcc , comstackz avec -Wall -pedantic (ou même avec -Wextra ), et assurez-vous de corriger chaque avertissement avant de continuer à programmer des fonctionnalités supplémentaires. Vous pouvez également indiquer au compilateur si vous écrivez ANSI C ( -ansi ) ou C99 ( -std=c99 ).

Quelques remarques:

  • Mettez des espaces après des virgules.
  • Faire main retour main un int .
    • Et faites-le return 0 ou return EXIT_SUCCESS .
  • Importez la définition de getch : #include .
    • Ou utilisez simplement getchar .
  • Importez la définition de memcpy : #include .
  • Ne retournez pas quelque chose dans une fonction void .
  • Vous pouvez utiliser malloc pour allouer un tampon de taille variable. Cela fonctionnera également avec les anciens compilateurs:

     void swap(void *p1, void *p2, int size) { void *buffer = malloc(size); memcpy(buffer, p1, size); memcpy(p1, p2, size); memcpy(p2, buffer, size); free(buffer); } 

Vous devez déclarer le swap avant de l’utiliser. Par exemple, mettez swap au-dessus de main ou ajoutez un prototype pour swap comme ceci:

 void swap(void *,void *,int); int main () 

Incidemment, main doit être int non void et renvoie généralement la valeur zéro, sauf erreur.

Tout d’abord, le message d’erreur réel ne ferait pas de mal.

Deuxièmement, créer un tampon de [taille] ne fonctionne que sur certains compilateurs (c’est une nouvelle fonctionnalité, mais tous les compilateurs ne l’ont pas encore). Êtes-vous sûr que le vôtre fait?

Troisièmement, vous devez déclarer le swap avant de l’appeler. Ajoutez un prototype en haut du fichier:

 void swap(void *p1,void *p2,int size); 

Vous n’avez pas déclaré explicitement votre swap , ce qui a forcé le compilateur à émettre des hypothèses sur la fonction au moment de l’appel. Conformément aux règles C, le compilateur supposera que l’ swap est

 int swap(int *, int *, size_t) 

Plus tard, vous déclarez votre échange comme

 void swap(void *, void *, int) 

ce qui est évidemment différent de ce que le compilateur a supposé. C’est le conflit dont le compilateur vous parle.

En outre, votre void swap tente de return 0 . Qu’essayiez-vous d’atteindre avec cela?

PS C’est int main , pas void main .

PPS Il n’est pas garanti que le programme produise une sortie si sa sortie ne se termine pas par un caractère de nouvelle ligne.

Vous vous demandez peut-être pourquoi le programme comstack sans un prototype pour swap (), car le compilateur est plus qu’un outil C99. Il comstack également les programmes C89 et K & R C.

C89 a ajouté les prototypes. Avant C89, le compilateur n’avait pas besoin de voir la déclaration (le prototype) d’une fonction à moins qu’il ne renvoie autre chose que int et que les types des parameters formels ne soient pas du tout connus du compilateur. Le compilateur vient d’appeler chaque fonction avec les types des arguments réels, qui ont reçu un ensemble de promotions d’arguments par défaut pour simplifier les choses. Le programmeur exécuterait l’utilitaire lint pour vérifier les parameters réels et formels. Ce programme est toujours livré avec les dissortingbutions BSD.

Les programmes K & R et les styles de code correspondants sont toujours acceptés par votre compilateur. Ainsi, lorsqu’il détecte une fonction pour laquelle aucun prototype n’est disponible, il se lance et l’appelle quand même.

Dans ce cas, vous permutez les paradigmes entre l’appel et la définition de la fonction. Les hypothèses de K & R C que le compilateur a formulées à propos de la fonction non déclarée lorsqu’il devait générer un appel se sont avérées non valides. Même si vous aviez écrit tout le programme dans le style K & R, le compilateur aurait fait les mêmes plaintes lorsqu’il aurait découvert les types réels des arguments de la fonction.

Avec GCC, ceci est un avertissement,
lorsque vous ne déclarez pas une fonction avant de l’utiliser, le compilateur essaie de deviner la déclaration en utilisant le type d’appel de cette fonction. Par conséquent, le comportement.

Eh bien, il comstack sur http://codepad.org (après avoir supprimé le getch() , ce qui n’est pas pertinent). Peut-être que votre compilateur se plaint d’utiliser Memcpy sur des pointeurs non restreints?

Dans swap() il n’est pas garanti que p1 et p2 ne soient pas des alias. Il s’agit d’un bogue en attente d’apparition – appeler un échange sur &a[i] et &a[j] pourrait faire exploser la memcpy quand i==j . Soit vous utilisez memmove (ce qui garantit de ne pas exploser sur les zones superposées), soit vous ressortingcted les pointeurs.