Partage
  • Partager sur Facebook
  • Partager sur Twitter

C sur VS Code undefined reference to 'fonction'

Programmation modulaire impossible sur VS Code

20 novembre 2022 à 1:52:01

Bonjour,

désolé d'avance pour les problèmes niveau rédaction c'est la première fois que j'utilise un forum.

Je n'arrive pas à utiliser des fonctions d'un autre fichier à moi

J'ai recrée ce que ca fait avec un code basique pour que vous compreniez plus facilement

main.c ->

#include <stdio.h>

#include <stdlib.h>

#include "helloworld.h"

int main(){

    helloWorld();

}

helloworld.c ->

#include <stdio.h>

#include <stdlib.h>

#include "helloworld.h"

void helloWorld(){

    printf("Hello World !");

}



helloworld.h ->

#ifndef HELLOWORLD.H

#define HELLOWORLD.H

#include <stdio.h>

#include <stdlib.h>

// Fonction helloWorld

void helloWorld();

#endif

Lorsque j'exécute donc le fichier main.c ca m'écrit ca :

Voici toute mes extensions activé sur mon VS Code :

Voilà

J'ai bien vu sur le forum le même problème notamment ici

-> https://openclassrooms.com/forum/sujet/cours-la-programmation-modulaire-26148

mais le problème n'est toujours pas résolu. 

Que ce soit sur Linux ou Windows mon code ne veut pas s'exécuter et me sort le même message d'erreur.

Le plus  étonnant est que j'ai un autre programme qui utilise mes fonctions écrit dans un autre fichier et celui-ci marche parfaitement bien, mais c'est le seul qui marche et  je l'ai codé sur Code::Block

J'ai donc essayé de reproduire le même processus, c'est à dire le coder sur Code::Block (ou le programme fonctionne) puis l'utiliser sur VS Code mais sans succès.

Voilà alors si vous avez des solutions je suis preneur  ! (problème d'extension ? De réglage VS ? Peut être le système de déboguage que je ne comprend pas ?)

Merci à vous :D

-
Edité par Hlkaeme_ 20 novembre 2022 à 20:00:17

  • Partager sur Facebook
  • Partager sur Twitter
20 novembre 2022 à 3:16:21

Bonjour ! Tout d'abord, modifie ton message pour que le programme soit mis dans dans l'éditeur de code, accessible par le bouton </>, avant que la modération ne s'aperçoive que tu n'as pas lu les instructions...

Est-ce que tu as lu les messages d'erreur ? Il faut les lire ! Je les ai lus : il n'accepte pas le point dans « #ifndef HELLOWORLD.H » (il y a une petite flèche qui désigne ce point) et dans le #define qui suit. Effectivement, j'ai toujours vu qu'on ne pouvait utiliser que les lettres et le caractère de soulignement (underscore) : « #ifndef HELLOWORLD_H ». Je te suggère d'utiliser le caractère de soulignement dans les deux lignes en question et voir si ça va mieux.

Attention : la fonction 'helloworld' est définie comme était de type 'void', évite de la mettre de type 'int' dans le prototype de "helloworld.h".

-
Edité par robun 20 novembre 2022 à 3:17:58

  • Partager sur Facebook
  • Partager sur Twitter
20 novembre 2022 à 8:58:38

Le .H est simplement un warning, pas une erreur. L'erreur est le problème de type de la fonction int/void.
  • Partager sur Facebook
  • Partager sur Twitter

Le crayon la gomme et le papier sont les meilleurs outils du programmeur !

20 novembre 2022 à 9:17:57

L'erreur apparait à l'édition des liens. La fonction n'est pas retrouvée car le projet doit indiquer les fichiers à compiler donc ici main.c et helloworld.c. Comme hellowold.c n'y est pas, il n'est pas compilé, et d'ailleurs c'est pour cela que l'erreur indiquant que la fonction helloWorld() n'a pas le même type de retour n'apparait pas.
  • Partager sur Facebook
  • Partager sur Twitter

En recherche d'emploi.

20 novembre 2022 à 14:13:55

robun a écrit:

Bonjour ! Tout d'abord, modifie ton message pour que le programme soit mis dans dans l'éditeur de code, accessible par le bouton </>, avant que la modération ne s'aperçoive que tu n'as pas lu les instructions...

Est-ce que tu as lu les messages d'erreur ? Il faut les lire ! Je les ai lus : il n'accepte pas le point dans « #ifndef HELLOWORLD.H » (il y a une petite flèche qui désigne ce point) et dans le #define qui suit. Effectivement, j'ai toujours vu qu'on ne pouvait utiliser que les lettres et le caractère de soulignement (underscore) : « #ifndef HELLOWORLD_H ». Je te suggère d'utiliser le caractère de soulignement dans les deux lignes en question et voir si ça va mieux.

Attention : la fonction 'helloworld' est définie comme était de type 'void', évite de la mettre de type 'int' dans le prototype de "helloworld.h".

-
Edité par robun il y a environ 10 heures

Merci pour ton message, j'ai corrigé la syntaxe de mon message merci de me l'avoir signalé :) 

Et en ce qui concerne les # je les ais corrigés mais toujours rien.
Et excusez moi pour l'erreur de void/int c'était une simple erreur présente que dans l'exemple et pas dans mon vrai programme, malheureusement la changer je résous toujours rien.

Dalfab a écrit:

L'erreur apparait à l'édition des liens. La fonction n'est pas retrouvée car le projet doit indiquer les fichiers à compiler donc ici main.c et helloworld.c. Comme hellowold.c n'y est pas, il n'est pas compilé, et d'ailleurs c'est pour cela que l'erreur indiquant que la fonction helloWorld() n'a pas le même type de retour n'apparait pas.


Il est possible que ce soit en effet une erreur de compilation mais comment dois-je m'y prendre pour régler ce problème ?

-
Edité par Hlkaeme_ 20 novembre 2022 à 14:17:46

  • Partager sur Facebook
  • Partager sur Twitter
20 novembre 2022 à 15:33:49

La compilation en C et C++ c'est pas de la magie, il ne suffit pas d'installer des extensions dans un IDE quelconque en espérant que ça marche. Il faut explicitement dire ce qu'il faut compiler et de quels fichiers objets sera constitué l'executable ou la librairie. Alors oui dans les IDE où le C et le C++ sont gérés nativement, il y a toute une abstraction sophistiquée pour que même une personne qui ne comprend rien à la compilation puisse s'en sortir sous peu qu'il ait créé les fichiers du projet via l'IDE, mais in fine pour un débutant cela peut être préjudiciable pour son apprentissage.

Bref tu dois écrire un fichier de build qui fonctionne pour le système de build que tu as choisi, et tu dois lui dire que tu veux compiler main.c et helloworld.c, puis créer un executable à partir de ces 2 unités de compilation.

Donc:

Solution 1: utilise l'espèce de truc non-standard fourni par l'extension C/C++ de VSCode à base de fichiers json, donc tu peux aller lire leur doc: https://code.visualstudio.com/docs/cpp/config-mingw#_modifying-tasksjson. Soyons clair, aucun développeur sérieux n'écrit un vrai programme avec ces json, c'est du bidouillage pour débutants.

Solution 2: écris un CMakeLists.txt. Tu as installé l'extension CMake Tools, donc autant que ça serve (il faut installer CMake tout de même: https://cmake.org/download/).

En supposant que tes fichiers main.c et helloworld.c sont dans le même répertoire que le fichier CMakeLists.txt, un tel fichier serait aussi simple que ça pour ton besoin:

cmake_minimum_required(VERSION 3.15)
project(foo LANGUAGES C)

add_executable(helloworld main.c helloworld.c)

Solution 3: d'autres build system (Meson, un Makefile pur, compiler en ligne de commande etc)

-
Edité par SpaceIn 20 novembre 2022 à 16:07:39

  • Partager sur Facebook
  • Partager sur Twitter
20 novembre 2022 à 18:13:05

Bonjour,

dans le .c

voidhelloWord()

dans le .h

inthelloWorld();

Sans regarder l'ourput de la compilation, je vois deja deux erreurs :

void != int

word != world

  • Partager sur Facebook
  • Partager sur Twitter

Mon jeu multi online gratuit : https://gamejolt.com/games/space-war/482884

20 novembre 2022 à 20:04:01

Gaziduc a écrit:

Bonjour,

dans le .c

voidhelloWord()

dans le .h

inthelloWorld();

Sans regarder l'ourput de la compilation, je vois deja deux erreurs :

void != int

word != world

Merci pour ta réponse mais j'ai déjà dis précédemment que ce fichier était qu'un exemple et que l'erreur n'y était pas sur mon vrai programme, juste une erreur de rédaction désolé, ils sont corrigés ! 

SpaceIn a écrit:

La compilation en C et C++ c'est pas de la magie, il ne suffit pas d'installer des extensions dans un IDE quelconque en espérant que ça marche. Il faut explicitement dire ce qu'il faut compiler et de quels fichiers objets sera constitué l'executable ou la librairie. Alors oui dans les IDE où le C et le C++ sont gérés nativement, il y a toute une abstraction sophistiquée pour que même une personne qui ne comprend rien à la compilation puisse s'en sortir sous peu qu'il ait créé les fichiers du projet via l'IDE, mais in fine pour un débutant cela peut être préjudiciable pour son apprentissage.

Bref tu dois écrire un fichier de build qui fonctionne pour le système de build que tu as choisi, et tu dois lui dire que tu veux compiler main.c et helloworld.c, puis créer un executable à partir de ces 2 unités de compilation.

Donc:

Solution 1: utilise l'espèce de truc non-standard fourni par l'extension C/C++ de VSCode à base de fichiers json, donc tu peux aller lire leur doc: https://code.visualstudio.com/docs/cpp/config-mingw#_modifying-tasksjson. Soyons clair, aucun développeur sérieux n'écrit un vrai programme avec ces json, c'est du bidouillage pour débutants.

Solution 2: écris un CMakeLists.txt. Tu as installé l'extension CMake Tools, donc autant que ça serve (il faut installer CMake tout de même: https://cmake.org/download/).

En supposant que tes fichiers main.c et helloworld.c sont dans le même répertoire que le fichier CMakeLists.txt, un tel fichier serait aussi simple que ça pour ton besoin:

cmake_minimum_required(VERSION 3.15)
project(foo LANGUAGES C)

add_executable(helloworld main.c helloworld.c)

Solution 3: d'autres build system (Meson, un Makefile pur, compiler en ligne de commande etc)

-
Edité par SpaceIn il y a environ 3 heures

Merci pour ton message, effectivement j'avais bien remarqué que la compilation en C/C++ n'était pas si simple mais personne ne le signalais vraiment souvent. D'après ce que j'ai compris la solution la plus optimal serait la solution 2 ? 

En tout cas je vais tenter celle là, merci à toi pour ton aide ! :D



-
Edité par Hlkaeme_ 20 novembre 2022 à 20:04:34

  • Partager sur Facebook
  • Partager sur Twitter
21 novembre 2022 à 10:14:52

Pour moi le plus simple est de compiler en ligne :

> cc main.c helloworld.c -o main.exe

où "cc" désigne le compilateur (s'il s'appelle "truc", remplacer "cc" par "truc").

Ainsi, pas besoin de se creuser la tête à paramétrer quoi que ce soit. (Je comprends qu'on ait envie d'apprendre à utiliser un IDE, mais ça peut venir plus tard.)

  • Partager sur Facebook
  • Partager sur Twitter
24 novembre 2022 à 22:50:07

robun a écrit:

Pour moi le plus simple est de compiler en ligne :

> cc main.c helloworld.c -o main.exe

où "cc" désigne le compilateur (s'il s'appelle "truc", remplacer "cc" par "truc").

Ainsi, pas besoin de se creuser la tête à paramétrer quoi que ce soit. (Je comprends qu'on ait envie d'apprendre à utiliser un IDE, mais ça peut venir plus tard.)


Merci, en effet je fais donc :

gcc fichier1.c fichier2.c -o main

.\main

Merci pour votre aide ! :D

  • Partager sur Facebook
  • Partager sur Twitter
24 novembre 2022 à 23:17:04

Hlkaeme_ a écrit:

          Merci, en effet je fais donc :

gcc fichier1.c fichier2.c -o main

.\main

Non. Tu ajoutes les options de compilation -Wall -Wextra (au minimum) et -std=c11

  • Partager sur Facebook
  • Partager sur Twitter

On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

24 novembre 2022 à 23:20:35

Comme je suis sous Linux, j'ai créé un alias :

alias cc='gcc -Wall -Wextra -pedantic -std=gnu11'

que j'ai mis dans le fichier ".bash_aliases". Tiens, je me rends compte que j'utilise std=gnu11 plutôt que std=c11. Bon...

-
Edité par robun 24 novembre 2022 à 23:21:41

  • Partager sur Facebook
  • Partager sur Twitter
25 novembre 2022 à 0:34:26

edgarjacobs a écrit:

Hlkaeme_ a écrit:

          Merci, en effet je fais donc :

gcc fichier1.c fichier2.c -o main

.\main

Non. Tu ajoutes les options de compilation -Wall -Wextra (au minimum) et -std=c11

Pourquoi ?

faire ce que j'ai dit marche

je suis curieux de savoir pourquoi je doit faire ca ?



-
Edité par Hlkaeme_ 25 novembre 2022 à 0:35:16

  • Partager sur Facebook
  • Partager sur Twitter
25 novembre 2022 à 8:27:39

Les options demandent au compilateur de t'aider à écrire des programmes qui marchent !

Le langage C est plein de trous. Sa norme permet d'écrire des choses qui sont connues comme peu recommandables (comparer des nombres signés et non signés, par exemple).

Le compilateur émet donc deux types de messages

  • Des messages d'erreur, au moins c'est clair, la compilation est refusée
  • Des avertissements, qui signalent les trucs louches.
Détails
  • -Wall  (warnings : all) demande d'avoir tous les avertissements standards par rapport au langage
  • -Wextra en donne un peu plus (les mauvaises utilisations classiques)

Quant à -std c'est pour préciser la norme a laquelle on veut se conformer. Ici C11, plutôt qu'on ne sait quoi (La version de C avec extensions, par défaut choisie pour cette version du compilateur). 

En pratique, 99 % des programmes n'ont pas besoin de faire des trucs que le compilateur trouvera louche ou non standard. Donc le bon choix c'est de mettre à fond la production d'avertissements, et de les faire disparaître en corrigeant le code (pas en enlevant les options) après avoir lu et compris les avertissements (pour ne pas recommencer).

Évidemment quand le boulot est de corriger en 10 minutes  un bug dans le programme écrit par un stagiaire peu soigneux il y a 15 ans, on ne va pas se lancer à rectifier le code pour éliminer les 150 avertissements qui apparaissent à chaque compilation. Mais dans le code qu'on écrit soi-même, l'hygiène de base c'est ZERO AVERTISSEMENT. 

Si on ajoute -Werror, les warnings sont considérés comme erreurs et font échouer la compilation. C'est plus radical. 

-
Edité par michelbillaud 25 novembre 2022 à 8:37:03

  • Partager sur Facebook
  • Partager sur Twitter
25 novembre 2022 à 10:39:18

Je dirais qu'il y a deux types d'erreur (en gros) : les erreurs de syntaxe ; les erreurs de programmation.

  • Les messages d'erreur du compilateur détectent les erreurs de syntaxe (il ne détectera pas un « if (n = 0) », ce n'est pas une erreur de syntaxe mais ce n'est sûrement pas ce que le programmeur voulait faire).
  • Les avertissements détectent des anomalies qui peuvent être des erreurs de programmation (l'exemple précédent est plutôt une erreur d'étourderie, mais ça peut arriver par exemple quand on utilise des pointeurs à mauvais escient : la syntaxe est permise, mais on fait n'importe quoi  je le sais, ça m'arrive assez souvent...)

-
Edité par robun 25 novembre 2022 à 10:44:05

  • Partager sur Facebook
  • Partager sur Twitter
25 novembre 2022 à 18:01:29

Je reconnais avoir été laconique dans mon message. Merci à @michelbillaud et @robun d'avoir expliqué pourquoi ces options sont nécessaires.

-
Edité par edgarjacobs 25 novembre 2022 à 18:03:59

  • Partager sur Facebook
  • Partager sur Twitter

On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent