2022-03-25, 21:49
  #1
Medlem
Bromsklosss avatar
Här har vi en kodsnutt med en "free" för mycket. Med optimeringsnivå 0 får man en varning, som väntat, men inte med optimeringsnivå 1 eller högre. Det är som om om analysen på något sätt skulle göras efter att "malloc" och "free" optimerats bort. Är det verkligen menat så här? Då missar man ju fel i koden för att de råkade försvinna i optimeringen.

-O0 -fanalyzer
-O1 -fanalyzer
Citera
2022-03-25, 22:25
  #2
Medlem
Enterprises avatar
Citat:
Ursprungligen postat av Bromskloss
Här har vi en kodsnutt med en "free" för mycket. Med optimeringsnivå 0 får man en varning, som väntat, men inte med optimeringsnivå 1 eller högre. Det är som om om analysen på något sätt skulle göras efter att "malloc" och "free" optimerats bort. Är det verkligen menat så här? Då missar man ju fel i koden för att de råkade försvinna i optimeringen.

-O0 -fanalyzer
-O1 -fanalyzer
Är inte exemplet lite väl hypotetiskt?

Ditt kodexempel åstadkommer ju ingenting och är det inte därför den optimerade koden blir extremt kort?

Kod:
main:
        mov     eax, 0
        ret

Dessa rader ju ut varandra eftersom p aldrig används:
Kod:
 char *p = malloc(sizeof (char));
 free(p);

Det är alltså inte bara onödigt att ha free två gånger utan ens en gång, likaså är mallocen onödig eftersom den allokerade snutten av minnet inte används.
__________________
Senast redigerad av Enterprise 2022-03-25 kl. 22:29.
Citera
2022-03-26, 09:42
  #3
Moderator
vhes avatar
Citat:
Ursprungligen postat av Enterprise
Det är alltså inte bara onödigt att ha free två gånger utan ens en gång, likaså är mallocen onödig eftersom den allokerade snutten av minnet inte används.

Jag tror nog att Bromskloss är medveten om det. Det är ju trots allt bara exempelkod för att peka på GCC:s beteende. Frågan är ju om det är väntat beteende att kompilatorn inte varnar för dålig kod om den råkar optimeras bort. Man hade ju naivt kunnat tycka att det skall varnas för problem i källkoden, inte den resulterande maskinkoden.
Citera
2022-03-26, 10:55
  #4
Medlem
Enterprises avatar
Citat:
Ursprungligen postat av vhe
Jag tror nog att Bromskloss är medveten om det. Det är ju trots allt bara exempelkod för att peka på GCC:s beteende. Frågan är ju om det är väntat beteende att kompilatorn inte varnar för dålig kod om den råkar optimeras bort. Man hade ju naivt kunnat tycka att det skall varnas för problem i källkoden, inte den resulterande maskinkoden.
Tankefel av mig. Jag tänkte på att optimering av maskinkod verkade fungera men det borde ju finnas en varning för onödig källkod också
Citera
2022-03-26, 15:02
  #5
Medlem
Citat:
Ursprungligen postat av Enterprise
Tankefel av mig. Jag tänkte på att optimering av maskinkod verkade fungera men det borde ju finnas en varning för onödig källkod också

Varningar är ju inte en del av språkets standard. Kompileringsfel däremot är det ju.
Och GCCs främsta funktion är att följa standarden så väl det går.
Inte för att leta efter "dålig kod".
Man kan skriva jäkligt dålig kod och den går igenom och är körbar ändå.
Just operatorn free() följer väl bara standarden. Är den byggd enligt specifikationerna så räcker det. Det är inget principiellt fel enligt standarden att använda free två gånger eller fler på samma pekare.
Det är definitivt bad programming practice, men inget som ger kompileringsfel.
Varningar har kommit till därför att det finns programmerare som har klagat på att kompilatorn ska minsann varna på vissa saker för att det kan kosta många arbetstimmar extra för en professionell programmerare att leta efter vad som händer med koden när den körs.
Inte så lätt att förstå.
De flesta varningar har tillkommit just för att spara arbete.
Och en del gamla varningar hade just med syntaxordet const att göra.
En annan utveckling tog det dock med syntaxordet const, där det blev infört i standarden.
Men const kan i själva verket tycker jag själv försvåra förståelsen och läsningen av koden.

Det ser också ut som att const är ett av de svårare sakerna för studenter att lära sig utantill.
Därför borde man skippa det helt för nybörjare.

Det är ett mycket omdiskuterat ämne med malloc/free och så kallade smarta pekare är avsedda att förhindra sådana konstigheter som kan uppträda. Smarta pekare i C++ kan fungera bra, men det kan bli problem om du måste flytta koden till en annan kompileringsmiljö som inte kan kompilera smarta pekare-headers, källkod och libs. Där finns potentiellt väldigt många fallgropar där då.
Att man kan inte flytta sådan kod till andra miljöer.
Att det inte är särskilt enkelt gjort heller.

Visst borde du ta upp det här i GCCs användarforum.
Men det har stötts och blötts i miljontals inlägg.
Och man har också därför överdrivit problemets natur, i onödan.


Ett enkelt tips är att köra (f)grep på koden och räkna antalet malloc man hittar, och jämföra med antalet free man hittar.

Ett annat enkelt tips är att efter varje free(ptr) så skriver man statementet ptr = NULL, det gör att man inte kan använda free(ptr) direkt efter.
Och brukar definitivt alltid få en exception direkt.

Citat:
Ursprungligen postat av Enterprise
Tankefel av mig. Jag tänkte på att optimering av maskinkod verkade fungera men det borde ju finnas en varning för onödig källkod också

Öööh, nu är du ute och fiskar på djupa och grumliga vatten. Tankefel och tankebrottslingar sorteras av svenska STASI = EXPO, möjligen att EXPO infiltrerat GCC-communityn också ?
Nåväl, finns miljontals möjligheter att skriva urusel och onödig källkod på. Att en kompilator skulle kunna bli så smart att den skulle kunna sortera bort sådant, det förefaller som att kompilatorn vore bli minst lika smart som en erfaren programmerare.
Det lär den aldrig kunna bli.
En kompilator kan inte lära en programmerare att skriva bra kod.
Kompilatorn kommer alltid att bara förbli ett korkat program, en dum translator mellan källkod och maskinkod.
Devisen garbage in --> garbage out kommer alltid att gälla.

Man kan titta bakåt i tiden då man jobbade med hålkort och projekten var uppdelade i olika delar. Ville en grupp lägga till några ytterligare variabler de behövde, så fick de föreslå namn på dessa.
Och vid de större sammanträdena så tilldelades det de nya variabelnamnen då.

Det gjorde så småningom att stora program blev monolitiska giganter, där varje variabel kunde ha ett unikt namn genom hela programmet. Därför fanns det ofta ytterligare många hjälpvariabler som var avsedda att korta ner uträkningarna.
Det var liksom en helt annan arbetsordning.
Unika variabelnamn var på sätt och vis värdefullt när man skulle debugga.
Men för den oinvigde så framgick det inte så klart.

Det gjorde också att dåtidens datorutveckling gick ut på matcha behovet av stack- och heap-utrymme, som hela tiden ökade på grund av denna programmeringsstil.
Plus även att göra växlingsfilen, dvs swap-filen så smidig som möjligt.
Det gjorde också att CPUns hastighet utvecklades mycket långsamt.
Man kunde inte heller krympa minneskorten så att de skulle fungera ihop med högre hastigheter.

Men vad som var skillnaden mot dagens PC-miljö var att det i regel bara kördes ett fåtal program samtidigt i CPUn, till skillnad från PCn som kan ha många processer igång samtidigt.

Och funktionerna Watch, Inspect och liknande kom inte förräns man kunde debugga i realtid. Vilket inte gick förr, utan man fick se till att debugga genom att göra utskrifter.
Alla program kördes då i batchar, och det kunde bli mycket arbetsamt att tex göra större statistikbearbetningar.
Men det gjorde det också svårt att återanvända kod i nya projekt.
Man skrev därför om många vanliga funktioner/subrutiner på nytt, helt ifrån scratch.
Citera
2023-01-07, 18:43
  #6
Medlem
Enligt LWN.net:

Citat:
the analysis runs as an interprocedural analysis (IPA) pass on the GIMPLE static single assignment (SSA) intermediate representation

Kanske har vissa optimeringar redan gjorts när denna intermediate representation nås. Konsekvensen blir ju hursomhelst tokig. Ska man behöva köra GCC två gånger, först för att få varningar och sedan för att bygga?
Citera

Skapa ett konto eller logga in för att kommentera

Du måste vara medlem för att kunna kommentera

Skapa ett konto

Det är enkelt att registrera ett nytt konto

Bli medlem

Logga in

Har du redan ett konto? Logga in här

Logga in