UB in C: GCC può eseguire una funzione mai chiamata
Testo scritto con l’intelligenza artificiale a partire da una fonte citata, senza revisione umana prima della pubblicazione.
Un esempio mostra che l'uso di std::unreachable() ha spinto GCC 16.2 a spostare una scrittura su volatile in una funzione non invocata, con possibili effetti su dispositivi e sicurezza.
Con GCC 16.2 con l’opzione -O1, l’uso di std::unreachable() ha prodotto codice che esegue una funzione mai chiamata nel sorgente. L’esempio, pubblicato su habets.se, nasce per contestare l’idea che con comportamento indefinito “al massimo arriva un segfault”. L’autore scrive: è falso1.
Il frammento parte da una variabile globale volatile. Il commento nel codice chiede di immaginare un dispositivo a memoria mappata che controlla “motors and gears and stuff”. Il sorgente definisce due funzioni: serve_hot_chocolate() scrive 42 in device_command e poi chiama std::unreachable(). explode() scrive 3 nella stessa variabile1.
Nel post compare la definizione di std::unreachable(): “Invokes undefined behavior at a given point.” Il cuore dell’esempio è qui. L’autore mostra cosa succede quando si dichiara quel punto come irraggiungibile e si compila con le impostazioni indicate1.
Compilando con GCC 16.2 e -O1, l’assembly riportato è sintetico: serve_hot_chocolate() contiene una scrittura di 42 su device_command. explode() contiene una scrittura di 3, poi il ritorno. device_command risulta inizializzato a zero1.
Subito dopo, l’autore annota l’effetto che vuole evidenziare: “Exploding chocolate! The function explode() will be executed, even though it was never called!” Il comportamento osservato è l’esecuzione di explode() senza una chiamata esplicita nel sorgente. È la conseguenza dell’UB introdotto con std::unreachable() nel flusso mostrato1.
I nomi nel codice chiariscono l’intento dell’esempio. serve_hot_chocolate() imposta 42, poi dichiara “qui non si arriva mai”. explode() imposta 3. La variabile condivisa è volatile. Il commento la presenta come registro di un dispositivo a memoria mappata, così la differenza tra 42 e 3 sarebbe osservabile in uscita verso “motors and gears and stuff”1.
L’autore aggiunge un secondo spunto. Alcune persone insistono che dereferenziare un puntatore nullo sia “fine”. “It’ll just try to access address zero!” Il post introduce anche questo tema come parte della stessa tesi: l’idea che l’UB sia innocuo non regge ai fatti mostrati1.
Il punto di partenza del post è netto: dopo un precedente intervento su comportamento indefinito in C, alcuni sostenevano che si sa cosa farà il codice e che, nel peggiore dei casi, si ottiene un segfault. L’autore replica con un caso concreto, completo di sorgente e listato assembly con le esatte condizioni di compilazione: GCC 16.2 e -O11.
Nel materiale pubblicato c’è tutto quello che serve a riprodurre l’osservazione: il codice con std::unreachable(), la variabile volatile device_command impostata a 42 in serve_hot_chocolate() e a 3 in explode(), e l’output in assembly che accompagna la spiegazione. La chiosa è nella frase già citata: explode() viene eseguita “even though it was never called!”1.
Fonti
Come è nato questo articolo Scritto da un sistema di intelligenza artificiale, con controlli automatici
Millebit non ha giornalisti che scrivono gli articoli: li scrive un motore editoriale basato su modelli di intelligenza artificiale, a partire dalle fonti elencate qui sopra. Prima di uscire, ogni testo passa questi controlli:
- Fedeltà alle fonti. Un secondo passaggio toglie ogni affermazione che le fonti non sostengono. Valutazione su questo pezzo: 8,5/10.
- Anti-cliché. Un filtro scarta frasi fatte, enfasi e tic della prosa artificiale: superato.
- Giudizio editoriale. Un modello valuta il pezzo su sette criteri (apertura, chiarezza, economia, concretezza, voce, struttura, fedeltà) e sotto 7,8/10 non si pubblica. Questo articolo ha preso 8,0/10.
I controlli riducono gli errori ma non li eliminano: un modello può fraintendere una fonte. Per le decisioni importanti, risali alla fonte originale. Se trovi un errore, segnalacelo.
Per vedere Millebit nelle notizie principali di Google, aggiungilo alle tue fonti preferite. Oppure segui l’edizione di oggi, il feed RSS o La Sintesi.