clang Il linker ha esito negativo se non è stato utilizzato almeno -O2

Ho un comportamento strage in un semplice codice C che sto facendo a scopo didattico.

Se lo compilo con qualcosa di inferiore a -O2, si interrompe durante la link-edition con questo output.

$ make clang -Wall -march=native -pipe -c -g -D_DEBUG_ main.c clang -Wall -march=native -pipe -c -g -D_DEBUG_ functions.c clang -Wall -o main main.o functions.o Undefined symbols for architecture x86_64: "_getbit", referenced from: _getValueFromMatrix in functions.o "_setbit", referenced from: _populateMatrix in functions.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) make: *** [main] Error 1 

Non so se questo aiuti ma, ecco l’implementazione di setbit (); e getbit ();

 inline void setbit(uint64_t *inteiro, unsigned char pos) { *(uint64_t*)inteiro |= (uint64_t)1 << pos; } inline bool getbit(uint64_t inteiro, unsigned char pos) { return (inteiro & ((uint64_t)1 << pos)); } 

MODIFICARE:

functions.h

 #ifndef __FUNCTIONS_H__ #define __FUNCTIONS_H__ /* Funções para manipulação de bits */ inline void setbit(uint64_t *, unsigned char); inline void clearbit(uint64_t *, unsigned char); inline bool getbit(uint64_t, unsigned char); inline unsigned char getbitChar(uint64_t, unsigned char); char *uint64_t2bin(uint64_t, char *, int); #endif 

Include in main.c

 #include  #include  #include  #include  #include  #include "errors.h" #include "const.h" #include "types.h" #include "functions.h" 

solo in inline è la cosa giusta da usare, se esiste una definizione della funzione nel file .h. In pratica dice al compilatore che non dovrebbe produrre un codice per la funzione in ogni unità di compilazione (i tuoi file .c).

Se non esiste tale definizione nel file .h, come sembra qui, non usare affatto in inline , non ha senso.

Se la tua preoccupazione è l’efficienza delle altre funzioni nell’unità in cui definisci le tue funzioni inline , non ne hai davvero bisogno. Il compilatore integrerà qualsiasi funzione su cui ha le mani e dove i suoi criteri dicono che vale la pena farlo.

Se vuoi davvero che le definizioni appaiano nel file di intestazione in modo tale che tutte le unità possano vedere la definizione, usa inline . In tal caso dovresti includere una “istanziazione” della tua funzione in una sola unità, per assicurarti che il codice venga emesso esattamente una volta:

 extern inline void setbit(uint64_t *, unsigned char); extern inline void clearbit(uint64_t *, unsigned char); extern inline bool getbit(uint64_t, unsigned char); extern inline unsigned char getbitChar(uint64_t, unsigned char); 

Le funzioni inline non hanno alcuna definizione esterna, quindi quando il compilatore non riesce a -O0 (cosa che non farà a -O0 ), il linker non riesce a trovare una definizione e viene generato un errore. La soluzione più semplice è cambiare in inline in static inline . In linea non statica è difficile da usare, confuso e di solito non utile.