Buggfix Plus
Aktuellt datum och tid: 02.09 2019-11-21

Alla tidsangivelser är UTC + 1 timme




Svara på tråd  [ 9 inlägg ] 
Författare Meddelande
 Inläggsrubrik: Veka funktioner i GCC
InläggPostat: 12.36 2019-10-11 
Användarvisningsbild

Blev medlem: 16.33 2012-07-08
Inlägg: 1010
En sån här dag vill man springa runt i korridorerna på jobbet, i hopp om att finna ett kuddrum där man kan gå in, ta en kudde för ansiktet och bara skrika ut sin frustration!
Jag sitter med ett knippe filer som bildar nån sorts modul eller bibliotek.
Jag har ett antal funktioner som skall finnas, men som inte gör speciellt mycket. Vill man ha utökad funktionalitet så är tanken att man själv skriver en ny version av vissa funktioner, och överrider dem. Lite som objektorientering, men ändå inte, här är det helt vanlig C.
Biblioteket innehåller därför ett antal funktioner som försetts med "weak"-attribut.
I MinGW, med GCC 8.2.0 så hittar inte länkaren dessa veka funktioner alls. Märkligt. Utan "weak" länkar den snällt in defaultfunktionen.
Så gör jag ett test i Arduino, med AVR-GCC 5.4.0 (enligt deras changelog). Där länkas den veka funktionen alltid in, även om jag skapat en stark ersättare, utan "weak".
Samtidigt har jag sett detta göras på otaliga ställen av ST i deras HAL, men då kanske projektinställningarna är trimmade på något vis.

Vad är det som händer?


Upp
 Profil  
 
 Inläggsrubrik: Re: Veka funktioner i GCC
InläggPostat: 13.10 2019-10-11 
EF Sponsor
Användarvisningsbild

Blev medlem: 15.29 2005-05-10
Inlägg: 37974
Ort: Söderköping
Jag vet inte vad "weak" förväntas göra, men vi all normal länkning
så ersätter man en inbyggd funktion genom att ange en egan före
den inbyggda i biblioteks och objekt referenserna. De flesta länkare
tar första träffen som de hittar.


Upp
 Profil  
 
 Inläggsrubrik: Re: Veka funktioner i GCC
InläggPostat: 19.14 2019-10-11 
Användarvisningsbild

Blev medlem: 22.33 2005-12-09
Inlägg: 3551
Ort: Helsingborg
Synd att man inte utökar C-standarden med de explicita deklarationerna från C++ av sådant.

Jag har verkligen börjat gilla C# nu, de striktare kraven på explicit deklaration, begränsningarna och
minneskontrollerna gör att man tvingas avlusa sin kod ganska väl redan under utvecklingen. Känns
som att man ganska väl har spärrat det som medelmåttiga till svaga C/C++-programmerare ofta gått
vilse i pannkakan på.

I C# gnäller vi åt andra hållet, där vill vi att deklarationen "unsafe" ska ge oss möjligheter till C/C++
strösslad med inline assembler. Man blir aldrig nöjd... :D


Upp
 Profil  
 
 Inläggsrubrik: Re: Veka funktioner i GCC
InläggPostat: 20.11 2019-10-11 
Användarvisningsbild

Blev medlem: 11.56 2004-05-08
Inlägg: 3576
Ort: Stockholm
Wedge skrev:
En sån här dag vill man springa runt i korridorerna på jobbet, i hopp om att finna ett kuddrum där man kan gå in, ta en kudde för ansiktet och bara skrika ut sin frustration!

Ja ibland är det frustrerande.
Bilaga:
a_bad_day_in_office.gif

Kan det vara något problem med/förväxling mellan användningen av weak-attributet i funktionsdeklarationen vs funktionsdefinitionen? Jag gissar bara, men jag läste någonstans att attribut är "sticky" i gcc, så är funktionen deklarerad som weak i headerfilen så kanske det hänger med även till den nya "hårda" definitionen? Vad händer om man deklarerar funktionen utan weak och bara använder attributet i definitionen av den svagt länkade varianten?


Logga in för att visa de filer som bifogats till detta inlägg.


Upp
 Profil  
 
 Inläggsrubrik: Re: Veka funktioner i GCC
InläggPostat: 20.29 2019-10-11 

Blev medlem: 10.02 2009-05-08
Inlägg: 799
Ort: Lund
I avr-gcc fungerar naturligtvis __attribute__((weak)). Alla avbrottsvektorer har denna egenskap från början, och du skulle inte kunna ha några egna avbrottsrutiner om inte detta fungerade.

Ett enkelt exempel på weak: En fil foobar.c
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
void bar(void)
{
}

void foo(void)
{
    bar();
}

Anropar man foo så anropas bar som gör ingenting. En fil main.c som anropar foo():
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
void foo(void);

int main(void)
{
    foo();
}

Kompilera och kör
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
$ gcc -c foobar.c
$ gcc -o main main.c foobar.o
$ ./main
$
Ingenting, som väntat. Om vi nu ändrar main.c till
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
#include <stdio.h>

void foo(void);

void bar(void)
{
    printf("This bar is stonger than foobar's bar\n");
}

int main(void)
{
    foo();
}
och kompilerar
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
$ gcc -o main main.c foobar.o
foobar.o: In function `bar':
foobar.c:(.text+0x0): multiple definition of `bar'
/tmp/cc9I3mmY.o:main.c:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status

Gick inte så bra. Så första bästa funkar inte när samma symbol är definierad flera gånger.
Men nu lägger vi in weak på bar i foobar.c
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
void __attribute__((weak)) bar(void)
{
}

void foo(void)
{
    bar();
}
kompilerar och kör
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
$ gcc -c foobar.c
$ gcc -o main main.c foobar.o
$ ./main
This bar is stonger than foobar's bar
så tar bar() i main.c över bar() i foobar.c.
(deklarera man båda bar() som weak så tas däremot "första bästa" utan felmeddelande).


Upp
 Profil  
 
 Inläggsrubrik: Re: Veka funktioner i GCC
InläggPostat: 18.49 2019-10-12 

Blev medlem: 21.06 2011-01-29
Inlägg: 904
arvidb skrev:
Jag gissar bara, men jag läste någonstans att attribut är "sticky" i gcc, så är funktionen deklarerad som weak i headerfilen så kanske det hänger med även till den nya "hårda" definitionen? Vad händer om man deklarerar funktionen utan weak och bara använder attributet i definitionen av den svagt länkade varianten?

Det stämmer. Har man weak-attributet i en headerfil blir även den nya funktionen weak om man inkluderar headerfilen i den TU:n, och vilken funktion som används bestäms av i vilken ordning man länkar objektfilerna.


Upp
 Profil  
 
 Inläggsrubrik: Re: Veka funktioner i GCC
InläggPostat: 09.25 2019-10-14 
Användarvisningsbild

Blev medlem: 16.33 2012-07-08
Inlägg: 1010
Exempel där konstigheterna visar sig:
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
__attribute__((weak)) void my_func( unsigned char *rnd )
{
   memcpy( rnd, (unsigned char*) "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7", 8 );
}

void blaj()
{
   unsigned char * foo;
   my_func( foo );
}

Vekhetsattributet gör nånting väldigt mystiskt här. Länkningsfel i "blaj()", funktionen my_func() är odefinerad när jag kör MinGW-projektet.
Funktionen my_func skall ersättas av nånting seriöst i verkligt användande, medan en annan version av funktionen skall användas av Unit-tester.
I övrigt verkar det vara som nämnts i tråden, länkningen tar in första bästa definition. Det sägs kunna kringgås med "--whole-archive", så att en inlänkad vekling kan kastas ut när en stark symbol dyker upp. Jag har inte provat detta.
Får jag inte ordning på detta med weak så får det väl bli funktionspekare istället, men det känns lite... meeh...!
Eller skippa standardbeteendet och weak-attribut, och tvinga slutanvändaren att implementera ALLA alternativfunktioner själv. Ännu mer MEH!


Upp
 Profil  
 
 Inläggsrubrik: Re: Veka funktioner i GCC
InläggPostat: 11.53 2019-10-14 
Användarvisningsbild

Blev medlem: 16.33 2012-07-08
Inlägg: 1010
En liten seger, kanske tillfällig...
Jag samlade ihop alla "weak"-funktioner (definitionerna), och lade dem i en separat headerfil (!), som inkluderas där åtkomst till funktionerna behövdes (internt). Doesn't make sense, som de säger over därborta, men om det funkar så inte mig emot...
Deklarationerna, utan weak, hamnade som sig bör i en vanlig headerfil som inkluderas där den behövs, även i slutanvändarens kod.
Sen hade jag kanske tur med länkningsordningen, men en stark funktion kunde ersätta sin veka namne bara genom att finnas! Whee!
MinGW hittade veka funktioner, och även de starka definitionerna, vad kan en hacker mer begära? :)

Mindre tur i Arduinokoden, men där såg jag att länkningsordningen var sådan att projektfilen, .ino-filen, länkades först. Så ett par starka funktioner fick flytta in dit. Fult, men fungerande, och då jag bara kör en Mega2560 som tillfällig målmiljö och flugsmälla/debugginghjälpmedel fick det duga så.


Upp
 Profil  
 
 Inläggsrubrik: Re: Veka funktioner i GCC
InläggPostat: 17.49 2019-11-06 

Blev medlem: 16.10 2018-12-10
Inlägg: 31
Jag brukar skriva
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
void __attribute__((weak)) foo();

Vet inte om det gör någon skillnad.

Man kan i åtminstone GCC även skriva
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
#pragma weak foo

void foo();

weak är inte standardiserat så olika kompilatorer kan kanske hantera det lite olika, även olika implementationer av samma kompilator.


Upp
 Profil  
 
Visa inlägg nyare än:  Sortera efter  
Svara på tråd  [ 9 inlägg ] 

Alla tidsangivelser är UTC + 1 timme


Vilka är online

Användare som besöker denna kategori: Inga registrerade användare och 3 gäster


Du kan inte skapa nya trådar i denna kategori
Du kan inte svara på trådar i denna kategori
Du kan inte redigera dina inlägg i denna kategori
Du kan inte ta bort dina inlägg i denna kategori
Du kan inte bifoga filer i denna kategori

Sök efter:
Hoppa till:  
   
Drivs av phpBB® Forum Software © phpBB Group
Swedish translation by Peetra & phpBB Sweden © 2006-2010