[c] Undefined Reference

Salut a tous !
Jrévisais avant un partiel de C et je terminais un TP. mais a la compil j’ai un undefined reference to ‘difrationnel’ une fonction defini dans mon fichier rationnels.c
j’ai modifier le makefile en vain, ce que je comprend pas c que le fichier contenant la fonction difrationnel contient aussi ma structure RATIONNEL qui elle ne pose pas de probleme pendant la compil :confused:

voila un racapitulatif pour aider:

rationnels.o

rationnels.h

typedef struct rationnel {
   long numerateur;
   long denominateur;
} RATIONNEL;
[...]
extern int difrationnel(RATIONNEL a,RATIONNEL b,RATIONNEL * c);
[...]

noeud.h
et noeud.c


#include <stdlib.h>
#include <stdio.h>
#include "rationnels.h"
#include "noeud.h"

NOEUD * nouvelleFeuille(RATIONNEL r){
  NOEUD* tmp=(NOEUD*)malloc(sizeof(NOEUD));
  tmp->valeur=(RATIONNEL*)malloc(sizeof(RATIONNEL));
  ((RATIONNEL *)(tmp->valeur))->numerateur=r.numerateur;
  ((RATIONNEL *)(tmp->valeur))->denominateur=r.denominateur;
  tmp->gauche=NULL;
  tmp->droit=NULL;
  return tmp;
}
[...]
 // et si j'appel difrationnel ici il me sort l'erreur alors que plus haut jutilise RATIONNEL sans probleme !

Pleaze Help

cordialement

Je c pas si j’ai ete clair alors je rajoute les sources –> ici <–

Jvous en suppli c’est important

D’une : on est pas tes chiens
De deux : undefined reference to ‘difrationnel’

C’est le linker qui pose problème et donc ton Makefile : (M majuscule)

all : testnoeud

noeud.o : noeud.h noeud.c
	gcc -g -Wall -c noeud.c

testnoeud : testnoeud.c noeud.o
	gcc -g -Wall -o testnoeud testnoeud.c noeud.o rationnels.o

clean : 
	rm -f testnoeud noeud.o 
  1. Désolé, jvoulais pas paraitre “donneur d’ordre”
  2. merci d’avoir resolu ca tu déchire :smiley:
  3. pourquoi jdois donné rationnels.o a testnoeud et rien a noeud.o ? O_o

MErci encore

Cordialement

Juste comme ça :

  • quand tu compile un fichier source avec l’option c, c’est pour produire du code objet (*.o) relogeable
  • quand tu compile ton éxécutable, tu produis du code binaire (relogeable, mais ça … chut!) et il va chercher des adresses ça et là, et si tu fous pas les bons .o, il trouvera jamais. Point.

Ca veut dire koi relogeable ?

ça veut dire que tu peux l’inclure dans un autre programme, et c’est ce que tu fais avec ça:

gcc -g -Wall -o testnoeud testnoeud.c noeud.o rationnels.o

tu inclues (ou loges) noeud.o et rationnels.o dans le programme testnoeud pour pouvoir utiliser leurs fonctions

OK merci, mais alors quelle est la difference entre un .o et un .so ?

heu, là tu me poses une colle, je n’ai jamais utilisé de fichier .so [:paysan]

Bah pour info ca se compile avec -share, c’est les DLL a la Linux
mais jvois pas trop la différence !

les fichiers en lib*.a sont des librairies statiques
les fichiers en lib*.so sont des librairies dynamiques
ton fichier .o est un fichier a “moitié” compilé, il manque l’étape d’édition de liens.

avec cette ligne de commande

gcc -g -Wall -o testnoeud testnoeud.c noeud.o rationnels.o

ton fichier testnoeud.c sera compilé en .o, puis il y aura une édition de liens avec tes deux autres fichiers en .o pour te donner au final un fichier binaire éxécutable uniquement sur ta machine.

Note: l’édition de lien consiste à remplacer la fonction printf ( par exemple ) par son adresse dans la librairie libstdio.so ou libstdio.a

Je suis pas un pro de la compilation, mais en gros c est ca

Si si si ca me semble etre ca, mon cours me reviens :ane:

[HS]Ouah génial y’a les anciens smileys :bounce: :paf: :whistle: :MDR mais ils ont changer les tags :grrr: :non: :stuck_out_tongue: :sol: [/HS]

Mais difference entre .so et .a ?
.a c’est une lib de .o et .so est dynamique (c ca? :ane: ).
L’edition de lien ce fait pas dynamiquement et a cause de cela il y a des possibilités de failles a cause du sticky bit si par exemple on masque un printf par une fonction qui lance un bash par exple => droit root ?

Les .a ce sont des fichiers compilés et archivés, que l’éditeur de liens inclut comme un porc dans ton programme (en gros: si tu regarde ton source, tu devrais certainement y trouver le code des fonctions de base)

Les .so ce sont les shared objets, ou objets partés, qui se compilent avec -shared (et pas -share) et qui permettent de partager la mémoire entre plusieurs processus. Par exemple, chaque programme démarre la bibliothèque libmalloc.so.

Avec LD_PRELOAD tu peux charger une bibliothèque à la volée, ou tu peux le faire avec dlopen. Mais bref, c’est une autre histoire… de système ce coup ci :slight_smile: