web-dev-qa-db-fra.com

Référence non définie à main - collect2: ld a renvoyé 1 état de sortie

J'essaye de compiler un programme (appelé es3), mais quand j'écris depuis le terminal:

gcc es3.c -o es3

il apparaît ce message:

/usr/lib/gcc/i686-linux-gnu/4.4.5/../../../../lib/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: ld returned 1 exit status

"Que pouvais-je faire?"

39
noobsharp

Cela signifie que es3.c ne définit pas de fonction main et vous essayez de créer un exécutable à partir de celle-ci. Un exécutable doit avoir un point d’entrée, ce qui fait que l’éditeur de liens se plaint.

Pour compiler uniquement dans un fichier objet, utilisez la commande -c option:

gcc es3.c -c
gcc es3.o main.c -o es3

Ce qui précède compile es3.c dans un fichier objet, puis compile un fichier main.c qui contiendrait la fonction main et l’éditeur de liens fusionne es3.o et main.o dans un exécutable appelé es3.

49

Peut-être que votre fonction main a été commentée, par exemple. prétraitement. Pour savoir ce que le prétraitement fait, essayez gcc -C -E es3.c > es3.i puis regardez avec un éditeur dans le fichier généré es3.i (et cherchez main à l'intérieur de celui-ci).

Tout d’abord, vous devriez toujours (puisque vous êtes un novice) compiler avec

  gcc -Wall -g -c es3.c
  gcc -Wall -g es3.o -o es3

Le -Wall drapeau est extrêmement important et vous devriez toujours l’utiliser. Il indique au compilateur de vous donner (presque) tous les avertissements. Et vous devriez toujours écouter les avertissements, c’est-à-dire corriger votre fichier de code source es3.C jusqu'à ce que vous n'ayez plus d'avertissements.

Le -g drapeau est également important, car il demande à gcc de mettre des informations de débogage dans le fichier objet et dans l’exécutable. Vous pouvez ensuite utiliser un débogueur (comme gdb) pour déboguer votre programme.

Pour obtenir la liste des symboles dans un fichier objet ou un exécutable, vous pouvez utiliser nm.

Bien sûr, je suppose que vous utilisez un système GNU/Linux (et je vous invite à utiliser GNU/Linux si vous ne l'utilisez pas déjà).

13

Une possibilité qui n’a pas été mentionnée jusqu’à présent est que vous ne puissiez peut-être pas éditer le fichier que vous pensez être. c'est-à-dire que votre éditeur peut avoir un cwd différent de celui que vous aviez en tête.

Exécutez "more" sur le fichier que vous compilez pour vérifier qu'il a bien le contenu que vous espérez. J'espère que ça t'as aidé!

3
matthewatabet

Le fichier exécutable nécessite une fonction principale. Voir ci-dessous bonjour la démo du monde.

#include <stdio.h>
int main(void)
{
        printf("Hello world!\n");
        return 0;
}

Comme vous pouvez le constater, il existe une fonction principale. si vous n'avez pas cette fonction principale, ld signalera "référence non définie à main" "

vérifier mon résultat:

$ cat es3.c
#include <stdio.h>
int main(void)
{
    printf("Hello world!\n");
    return 0;
}
$ gcc -Wall -g -c es3.c
$ gcc -Wall -g es3.o -o es3
~$ ./es3
Hello world! 

veuillez utiliser $ objdump -t es3.o pour vérifier s’il existe un symbole principal. Voici mon résultat.

$ objdump -t es3.o

es3.o:     file format elf32-i386

SYMBOL TABLE:
00000000 l    df *ABS*  00000000 es3.c
00000000 l    d  .text  00000000 .text
00000000 l    d  .data  00000000 .data
00000000 l    d  .bss   00000000 .bss
00000000 l    d  .debug_abbrev  00000000 .debug_abbrev
00000000 l    d  .debug_info    00000000 .debug_info
00000000 l    d  .debug_line    00000000 .debug_line
00000000 l    d  .rodata        00000000 .rodata
00000000 l    d  .debug_frame   00000000 .debug_frame
00000000 l    d  .debug_loc     00000000 .debug_loc
00000000 l    d  .debug_pubnames        00000000 .debug_pubnames
00000000 l    d  .debug_aranges 00000000 .debug_aranges
00000000 l    d  .debug_str     00000000 .debug_str
00000000 l    d  .note.GNU-stack        00000000 .note.GNU-stack
00000000 l    d  .comment       00000000 .comment
00000000 g     F .text  0000002b main
00000000         *UND*  00000000 puts
3
Daniel

Dans mon cas, j'ai découvert que le void de la déclaration de fonction principale était manquant.

Auparavant, j'utilisais Visual Studio sous Windows et cela ne posait jamais de problème. Je pensais donc pouvoir le laisser de côté aussi.

1
silicoin

Vous pouvez simplement ajouter une fonction main pour résoudre ce problème. Juste comme:

int main()
{
    return 0;
}
0
贫贫贫贫僧