2010-03-13 5 views
3

J'écris un projet d'université C et suis tombé sur un comportement de compilateur que je ne comprends pas.Le compilateur est capable de trouver la fonction sans correspondance. Fichier h est mis à jour?

Dans ce fichier http://code.google.com/p/openu-bsc-maximveksler/source/browse/trunk/20465/semester/tasks/maman14/alpha/maman14/assembler/phaseOne.c?r=112 J'ai ajouté un appel à la fonction freeAsmInstruction(). Cette fonction est définie dans le fichier lineParser.c, mais je n'ai pas mis à jour le fichier d'en-tête lineParser.h correspondant pour inclure cette déclaration de fonction.

Pourquoi ce code compile-t-il? Je m'attendrais à ce que gcc échoue à compiler phaseOne.c jusqu'à ce que lineParser.h correct soit mis à jour avec la déclaration de freeAsmInstruction().

J'apprécierais une explication.

Merci, Maxim

Répondre

3

Le compilateur GCC assume une signature de fonction par défaut particulière. Pour obtenir un avertissement à ce sujet, compilez avec le drapeau -Wall:

gcc -Wall -c phaseOne.c 

cela vous donnera un avertissement de la forme:

phaseOne.c:2: warning: implicit declaration of function 'your func here' 

À moins que vous ayez une bonne raison, vous devriez toujours compilation avec le drapeau -Wall, et probablement d'autres drapeaux d'avertissement aussi.

+0

Merci pour la réponse. –

+0

Par exemple, j'utilise généralement -pedantic -Wall -Wextra -Wwrite-strings -Wconversion -Werror, puis supprime les indicateurs d'avertissement si nécessaire. –

+0

@Steve Ce serait un grand avantage pour l'humanité si GNU tournait au moins -Wall et -pedantic par défaut, et que vous deviez utiliser des options pour les désactiver. Mais je suppose qu'ils ont peur de briser les océans du code de merde là-bas. –

-1

Je viens d'écrire un exemple de programme dans deux fichiers séparés:

a1.c

#include <stdio.h> 

int main() { 
    // using the external object 

    testing(); 

    return 0; 
} 

qui appelle une fonction qui existe dans a2.c

void testing() { 
    printf("temp\n"); 
} 

puis tout ce que j'ai fait était de le compiler en utilisant la commande suivante:

$ gcc a1.c a2.c -o a1 

et Travaillé

En fait, lorsque vous avez compilé votre dossier Avez-vous inclus l'autre fichier C (lineParser.c) dans l'étape de compilation à parser avec votre fichier ParseOne.c?

Dans ce cas, ce que je comprends est que gcc analyserait réellement tous les symboles dans les fichiers C associés (ou les fichiers obj) et les remplacerait de manière appropriée dans le fichier objet final à créer.

Espérons que cela aide.

1

Les fonctions non définies ne sont pas automatiquement une erreur; le compilateur les prend pour avoir un prototype par défaut, puis quand votre code est finalement lié s'il y a quelque chose du bon nom, il sera utilisé. Cependant, si le prototype par défaut n'est pas ce que votre fonction a réellement, ses arguments seront mal configurés (pensez à marteler une cheville carrée dans un trou rond); les conséquences seront imprévisibles.

Dans la plupart des cas, vous devriez dire au compilateur de traiter de tels cas comme une erreur. Par exemple, sur gcc, ajoutez -Wall -Werror à chaque ligne de compilation, ou ajoutez-les aux CFLAGS dans un Makefile type.

Questions connexes