2013-04-19 10 views
9

Ho finalmente rintracciato un errore di battitura, che è qualcosa di simile al seguente codice. Ma il compilatore non dovrebbe rilevarlo (per impostazione predefinita)?Perché il compilatore consente di inizializzare una variabile con se stessa?

#include <stdio.h> 

int main() 
{ 
    int c = c; 
    return printf("%d\n", c); 
} 


$ gcc --version   
gcc (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3 
+10

Si invoca un comportamento non definito con l'inizializzazione; il compilatore non ha bisogno di diagnosticare il problema o di definire cosa fa quando lo incontra. –

+8

Scommetto la mia scarpa sinistra che quando attivi gli avvisi (-Wall in GCC), ti avviserà quando lo farai. Cerca di non ignorare gli avvisi ;-) Viene rilevato – nothrow

+0

vc. – BLUEPIXY

risposta

7

Non vedo perché non si compila. La definizione avviene prima dell'inizializzazione. Ovviamente questa inizializzazione è inutile, tuttavia, non c'è motivo per cui non funzionerebbe dal punto di vista dei compilatori.

C non ha gli stessi tipi di protezione che hanno linguaggi più moderni come C#. Il compilatore C# darebbe un errore sul fatto che stai usando una variabile non assegnata. A C non importa. Non ti proteggerà da te stesso.

+5

Questa inizializzazione, non assegnazione. –

+5

Inoltre, essere in grado di fare riferimento alla variabile per la sua inizializzazione è * utile *, perché puoi prendere il suo indirizzo, come in 'int x = initialize_and_register (& x)'. (Questo tipo di invocazione verrebbe tipicamente inserito in una macro). – user4815162342

+0

@ user4815162342 true, ovviamente ha senso. Avrei dovuto scegliere le mie parole meglio :( – evanmcdonnal

-3

Se

int c; 
c = c; 

compilerà, non vedo il motivo per cui int c = c; non verrà compilato.

+7

I due sembrano ingannevolmente simili, ma in realtà sono piuttosto diversi: "int c = ..." è l'inizializzazione piuttosto che l'assegnazione. Ad esempio, 'int c [] = {1, 2, 3};' funziona ma '{1, 2, 3}' non è valido nel contesto di un compito. – delnan

5

È perfettamente legittimo utilizzare una variabile nel proprio inizializzatore. Si consideri una lista collegata:

#include <stdio.h> 
struct node { struct node *prev, *next; int value; }; 
int main() { 
    struct node l[] = {{0, l + 1, 42}, {l, l + 2, 5}, {l, 0, 99}}; 
    for (struct node *n = l; n; n = n->next) 
     printf("%d\n", n->value); 
    return 0; 
} 

In generale, la diagnosi quando un valore viene utilizzato Non inizializzato è un problema difficile; sebbene alcuni compilatori possano rilevarlo in alcuni casi, non ha senso richiedere che ciò accada.

+0

Come è legittimo il comportamento non definito? – rubenvb

+8

Questo non sta inizializzando una variabile con se stessa, ma piuttosto un puntatore a se stesso, poiché 'l' decade in un puntatore' & [0] 'in questo contesto. –

+0

Quindi questo è definito? – this

Problemi correlati