J'ai un programme composé de plusieurs .c qui avaient étés compilé en 32bits. J'ai maintenant installé un compilateur 64bits, mais si la compilation se passe bien, le linker (ld) me met des erreurs. Je comprends bien le message qu'il met, mais ce que je comprends pas, c'est le pourquoi.
J'utilise cette version de gcc
gcc (MinGW-W64 x86_64-ucrt-posix-seh, built by Brecht Sanders) 12.2.0
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
J'exécute make
GNU Make 4.2
This program is built by Equation Solution <http://www.Equation.com>.
Copyright (C) 1988-2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
gcc -Wl,--subsystem=windows -obin/clrt.exe clrt.o clrt_sdl.o clrt_products.o clrt_display.o clrt_doit.o clrt_commands.o clrt_printlist.o clrt_ico.o ..\pglib\pgprint.o -lmingw32 -lsdl2main -lsdl2 -lsdl2_ttf -lsdl2_image -lGdi32 -lwinspool -lpg
d:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: clrt_sdl.o:clrt_sdl.c:(.bss+0x0): multiple definition of `clrt'; clrt.o:clrt.c:(.bss+0x0): first defined here
d:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: clrt_products.o:clrt_products.:(.bss+0x0): multiple definition of `clrt'; clrt.o:clrt.c:(.bss+0x0): first defined here
d:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: clrt_display.o:clrt_display.c:(.bss+0x0): multiple definition of `clrt'; clrt.o:clrt.c:(.bss+0x0): first defined here
d:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: clrt_doit.o:clrt_doit.c:(.bss+0x0): multiple definition of `clrt'; clrt.o:clrt.c:(.bss+0x0): first defined here
d:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: clrt_commands.o:clrt_commands.:(.bss+0x0): multiple definition of `clrt'; clrt.o:clrt.c:(.bss+0x0): first defined here
d:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: clrt_printlist.o:clrt_printlist:(.bss+0x0): multiple definition of `clrt'; clrt.o:clrt.c:(.bss+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
make: *** [makefile:9: bin/clrt.exe] Error 1
Merci d'avance pour votre aide.
Edgar;
NB: supprimer LFLAGS ne change rien, et pg est une lib personnelle.
- Edité par edgarjacobs 17 juin 2023 à 15:51:10
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
J'ai réussi à reproduire ton problème : J'ai créé une variable global dans un fichier entête que j'ai inclus dans 2 fichier sources et que j'ai compilé ensemble :
Avec les anciennes versions de minGW ça passe sans erreur (32 comme 64 bits)
Puis j'ai compilé avec minGW (gcc12) et là j'ai bien l'erreur ! La même que toi.
EDIT : J'ai testé sous Visual studio C ça compile, ce qui semblerait normal puisque si elles ne sont pas initialisées.
EDIT : J'ai testé aussi sous clang et la ça ne passe pas !
Il y aurait donc de divergences selon les compilateurs ?
PS : j'ai trouvé ça sur la norme : If a translation unit contains one or more tentative definitions for an identifier, and the translation unit contains no external definition for that identifier, then the behavior is exactly as if the translation unit contains a file scope declaration of that identifier, with the composite type as of the end of the translation unit, with an initializer equal to 0.
J'ai réussi à reproduire ton problème : J'ai créé une variable global dans un fichier entête que j'ai inclus dans 2 fichier sources et que j'ai compilé ensemble :
Avec les anciennes versions de minGW ça passe sans erreur (32 comme 64 bits)
Puis j'ai compilé avec minGW (gcc12) et là j'ai bien l'erreur ! La même que toi.
Waouuw ! Je me demande comment tu as pensé à ça en voyant le message d'erreur, car il faut avouer qu'il n'est pas très explicite !
J'ai en effet dans un common.h (inclus dans tous les .c) une variable globale, struct clrt *clrt; (ça évite de devoir la trimbaler de fonction en fonction). Et dans le main(), j'ai struct clrt sclrt={0}; clrt=&sclrt;
Avec minGW v9 (ou v6 ?), ça passe, mais avec v12 (comme tu l'as testé), ça casse.
La solution: dans common.h, déclarer extern struct clrt *clrt; et dans le .c qui contient le main() **, mettre struct clrt *clrt; en variable globale, et l'initialiser dans le main() (comme écrit plus haut, p.ex.)
rouloude, je te remercie énormément. Tu me sors d'une bien mauvaise passe. Ça vaut plus qu'un +1
Edgar;
PS: clang et minGW ont apparement raison, si je comprends bien.
** en fait, après test, en variable globale dans n'importe quel fichier .c du projet et initialisée n'importe où avant de l'utiliser.
- Edité par edgarjacobs 17 juin 2023 à 20:53:18
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
Après avoir corrigé l' "erreur", je me suis dit "je plains le bonhomme qui doit faire des modifications dans un pgm compilé avec ancien gcc, et le compiler avec un gcc récent".
Avec ta remarque, je me souviens d'avoir lu un article dans lequel l'auteur expliquait que les développeurs de compilateurs conservaient les éventuels "bugs" d'une version à l'autre, pour que les programmes utilisant la nouvelle version aient toujours le même comportement. L'option -fcommon me semble donc logique.
- Edité par edgarjacobs 18 juin 2023 à 15:42:02
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
On est d'accord que "créer" n'est pas le mot approprié. Pour le reste je suis aussi d'accord, mais ici j'essayer de reproduire une erreur et non pas de faire un code fonctionnel.
michelbillaud a écrit:
Avec un petit effort de vocabulaire
Soit tu définis
Soit tu déclares.
Dans ce sujet on serait dans ce qu'ils appellent une définition provisoire 'A tentative definition '.
Éviter de "définir dans n'importe quel fichier", autant que d'avoir un .h fourre-tout.
Le "Éviter de définir ...." c'était juste par souci de précision, mais d'accord avec toi.
Le common.h n'est pas un fourre-tout, il contient les define nécessaires au programme, et une structure qui retient les paramètres nécessaires au fonctionnement de l'application, style taille de la fenêtre etc, et un pointeur sur cette structure pour éviter de devoir se le coltiner de fonction en fonction, certaines n'en ayant pas besoin mais celles qu'elles appellent, oui.
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
Problème de linker
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent