Sia in C che in C ++, penso che questo programma illegale, il cui comportamento secondo lo standard C o C ++ non è definito, sia interessante:
#include <stdio.h>
int foo() {
int a;
const int b = a;
a = 555;
return b;
}
void bar() {
int x = 123;
int y = 456;
}
int main() {
bar();
const int n1 = foo();
const int n2 = foo();
const int n3 = foo();
printf("%d %d %d\n", n1, n2, n3);
return 0;
}
Output sulla mia macchina (dopo la compilazione senza ottimizzazione):
123 555 555
Penso che questo programma illegale sia interessante perché illustra la meccanica dello stack, perché la ragione per cui si usa C o C ++ (invece di, per esempio, Java) è programmare vicino all'hardware, vicino alla meccanica dello stack e simili.
Tuttavia, su StackOverflow, quando il codice di un interrogatore inavvertitamente legge dallo storage non inizializzato, le risposte con maggiore scalabilità citano invariabilmente lo standard C o C ++ (specialmente C ++) per l'effetto che il comportamento non è definito. Questo è vero, naturalmente, per quanto riguarda gli standard - il comportamento è davvero indefinito - ma è curioso che risposte alternative provino, da un punto di vista hardware o stack-meccanico, per indagare sul perché specifico il comportamento non definito (come l'output sopra) potrebbe essersi verificato, è raro e tende ad essere ignorato.
Ricordo persino una risposta che suggeriva che comportamento indefinito potrebbe includere la riformattazione del mio disco rigido. Non mi sono preoccupato troppo di questo, però, prima di eseguire il programma sopra.
La mia domanda è questa: Perché è più importante insegnare ai lettori semplicemente che il comportamento non è definito in C o C ++, piuttosto che capire il comportamento indefinito? Voglio dire, se il lettore capisce il comportamento non definito, quindi non sarebbe il più probabile per evitarlo?
La mia istruzione è in ingegneria elettrotecnica e lavoro come ingegnere edile e l'ultima volta che ho avuto un lavoro come programmatore per sé è stato nel 1994, quindi sono curioso di comprendere la prospettiva degli utenti con sfondi di sviluppo software più convenzionali e più recenti.