Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Fonction inline

5 réponses
Avatar
JKB
Bonjour Í  tous,

J'obtiens une erreur que je ne m'explique pas dans l'édition des
liens d'un firmware compilé avec avr-gcc.

J'ai écrit ceci :

void
freqdiv(uint8_t diviseur)
{
mutex_lock(&mutex_freqdiv);

if ((CLKPR & 0x0F) != diviseur)
{
stty_print("freqdiv ");
stty_hexprint(CLKPR & 0x0F);
stty_print("->");
stty_hexprint(diviseur);
stty_print("\r\n");

while(uart0_BytesToSend() > 0);

ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
diviseur &= 0x0F;
CLKPR = (1 << CLKPCE);
CLKPR = diviseur;
}
...
}
...
}

L'édition des liens me répond :

make[1] : on quitte le répertoire «Â /home/bertrand/cvs/firmware-antivol4/usart »
/usr/local/cross/avr/bin/avr-gcc -mmcu=atmega1284 -Wl,-Map,firmware.map -o firmware.elf main.o affichage.o interruptions.o io.o spi.o vfd.o mcp3001.o mcp23s08.o random.o stty.o leds.o horloge.o badges.o task_25Hz.o task_gnss.o gnss.o satellites.o synchronisation.o rscombo.o trame.o derivation_clefs.o task_boutons.o task_affichage.o eui64.o lorawan.o task_lorawan.o task_commandes.o task_puissance.o programmation.o iso14443a.o clrc632.o task_nfc.o usart/libusart.a crypto/libcrypto.a lorawan/liblorawan.a multitasking/libmultitasking.a \
-Wl,-u,vfprintf -lprintf_flt -lm
/usr/local/cross/avr/lib/gcc/avr/11.1.0/../../../../avr/bin/ld: task_25Hz.o: in function `freqdiv':
/home/bertrand/cvs/firmware-antivol4/task_25Hz.c:47: undefined reference to `uart0_BytesToSend'
collect2: error: ld returned 1 exit status
make: *** [Makefile:68 : firmware] Erreur 1

Ce que je ne saisis pas, c'est que cette fonction est une fonction
inline définie dans une bibliothèque que j'utilise (libusart pour
avoir un vrai port série avec RTS et CTS).

J'ai regardé ce que me sort le compilo avec l'option -E :

...
void uart0_flush(void);

extern volatile uint8_t tx0_Head, tx0_Tail;
inline uint8_t uart0_BytesToSend(void) { return (tx0_Head - tx0_Tail - 1) & (128 - 1); }
# 1836 "usart/usart.h"
char uart0_getc(void);
...

puis la ribambelle d'includes et mon code qui est inclus comme ceci
:

# 53 "task_25Hz.c"
& 0x0F);
stty_print("->");
stty_hexprint(diviseur);
stty_print("\r\n");

while(uart0_BytesToSend() > 0);

Je ne comprends pas pourquoi une fonction inline déclarée comme ceci
provoque un problème Í  l'édition des liens.

Je suis preneur de toute explication.

Merci d'avance,

JKB

--
Si votre demande me parvient en code 29, je vous titiouillerai volontiers
une réponse.

5 réponses

Avatar
Stephane Tougard
On 2022-01-31, JKB wrote:
Bonjour Í  tous,
J'obtiens une erreur que je ne m'explique pas dans l'édition des
liens d'un firmware compilé avec avr-gcc.
make[1] : on quitte le répertoire «Â /home/bertrand/cvs/firmware-antivol4/usart »
/usr/local/cross/avr/bin/avr-gcc -mmcu=atmega1284 -Wl,-Map,firmware.map -o firmware.elf main.o affichage.o interruptions.o io.o spi.o vfd.o mcp3001.o mcp23s08.o random.o stty.o leds.o horloge.o badges.o task_25Hz.o task_gnss.o gnss.o satellites.o synchronisation.o rscombo.o trame.o derivation_clefs.o task_boutons.o task_affichage.o eui64.o lorawan.o task_lorawan.o task_commandes.o task_puissance.o programmation.o iso14443a.o clrc632.o task_nfc.o usart/libusart.a crypto/libcrypto.a lorawan/liblorawan.a multitasking/libmultitasking.a
-Wl,-u,vfprintf -lprintf_flt -lm
/usr/local/cross/avr/lib/gcc/avr/11.1.0/../../../../avr/bin/ld: task_25Hz.o: in function `freqdiv':
/home/bertrand/cvs/firmware-antivol4/task_25Hz.c:47: undefined reference to `uart0_BytesToSend'
collect2: error: ld returned 1 exit status
make: *** [Makefile:68 : firmware] Erreur 1

Bon je dis peut-être (surement) une connerie parce que je connais pas
cette lib, mais dans la version actuelle que j'ai trouvé sur Github,
cette fonction est commentée.
--
On leur dit: "eux gentils". Ils disent "OK"
On leur dit: "eux méchants". Ils disent "OK"
Qu'est ce qu'ils sont cons ces pauvres !
Avatar
Arnaud DUMERAT
Bonjour,
la definition de uart0_BytesToSend est elle exposee dans libusart.a ? a
en croire ld, non.
deux solutions (ou plus): passer en always inline (attribute) ou forcer
l'export par exemple avec un -whole-archive dans la creation du .a ou
verifier pourquoi la reference a cette definition est effacee de
l'archive
Avatar
JKB
Le 09-02-2022, Arnaud DUMERAT a écrit :
Bonjour,

Bonjour,
la definition de uart0_BytesToSend est elle exposee dans libusart.a ? a
en croire ld, non.

Nous sommes bien d'accord. Mais il me semblait qu'une fonction
inline était traitée par le compilateur et non par l'éditeur de lien
(puisqu'elle était justement inline).
deux solutions (ou plus): passer en always inline (attribute) ou forcer
l'export par exemple avec un -whole-archive dans la creation du .a ou
verifier pourquoi la reference a cette definition est effacee de
l'archive

Effectivement, je vois dans la doc de gcc un
__attribute__((always_inline))
que je ne connaissais pas. Mais quelle serait la raison pour
laquelle gcc refuserait silencieusement d'honorer le inline de la
fonction en question ?
Bien cordialement,
JKB
--
Si votre demande me parvient en code 29, je vous titiouillerai volontiers
une réponse.
Avatar
Arnaud DUMERAT
je vous suggère la lecture du chapitre gcc concernant les fonctions
inline, qui mentionne différents cas d'optimisations pour lesquelles
l'inlining peut être sous optimal; l'utilisation de mots clefs
complémentaires peut aussi intervenir. le standard C n'étant que
suggestif sur le mot clef inline, toute liberté est laissée au
compilateur si il n'y a que cet attribut.
Hors modification de code, je vous suggérerais plutÍ´t un whole-archive
qui au regard de la taille de l'archive et de son utilisation pourrait
être adapté, Í  moins que la place ou un éventuel code mort ne soient
vraiment un problème.
Le jeudi 10 février 2022 Í  07:03 +0000, JKB a écrit :
Le 09-02-2022, Arnaud DUMERAT a écrit :
Bonjour,

        Bonjour,
la definition de uart0_BytesToSend est elle exposee dans libusart.a
? a
en croire ld, non.

        Nous sommes bien d'accord. Mais il me semblait qu'une
fonction
        inline était traitée par le compilateur et non par l'éditeur
de lien
        (puisqu'elle était justement inline).
deux solutions (ou plus): passer en always inline (attribute) ou
forcer
l'export par exemple avec un -whole-archive dans la creation du .a
ou
verifier pourquoi la reference a cette definition est effacee de
l'archive

        Effectivement, je vois dans la doc de gcc un
        __attribute__((always_inline))
        que je ne connaissais pas. Mais quelle serait la raison pour
        laquelle gcc refuserait silencieusement d'honorer le inline
de la
        fonction en question ?
        Bien cordialement,
        JKB
Avatar
JKB
Le 10-02-2022, Arnaud DUMERAT a écrit :
je vous suggère la lecture du chapitre gcc concernant les fonctions
inline, qui mentionne différents cas d'optimisations pour lesquelles
l'inlining peut être sous optimal; l'utilisation de mots clefs
complémentaires peut aussi intervenir. le standard C n'étant que
suggestif sur le mot clef inline, toute liberté est laissée au
compilateur si il n'y a que cet attribut.
Hors modification de code, je vous suggérerais plutÍ´t un whole-archive
qui au regard de la taille de l'archive et de son utilisation pourrait
être adapté, Í  moins que la place ou un éventuel code mort ne soient
vraiment un problème.

Merci, je vais regarde ça.
JKB
--
Si votre demande me parvient en code 29, je vous titiouillerai volontiers
une réponse.