Blocca le lingue scopate e con funzioni

4

Ho notato che alcuni linguaggi come C, C ++, Java, Perl e .NET Visual Basic hanno un ambito di "blocco", il che significa che una variabile verrà definita solo all'interno del blocco di codice specifico in cui è stato dichiarato.

Ad esempio (C ++):

if (true) {
    int x = 1;
}
std::cout << x << std::endl;

Questo codice non verrà compilato poiché x è visibile solo all'interno dell'ambito del blocco creato dall'istruzione if .

error: 'x' was not declared in this scope

Ma linguaggi come VBA, Python e Javascript hanno un ambito "basato sulla funzione", il che significa che l'unica volta che viene creato un nuovo ambito è quando viene definita una nuova funzione.

Ad esempio (VBA):

If True Then
    Dim x As Integer
    x = 1
End If
MsgBox(x)

Questo codice viene eseguito correttamente e il valore di x è visibile al di fuori dell'istruzione if .

Questo tipo di ambito mi sembra piuttosto confuso perché visivamente sembra che x debba "appartenere" all'istruzione if .

Quindi questo solleva la domanda: ci sono dei vantaggi oltre al semplice aspetto ... come vantaggi di prestazioni / vantaggi di velocità di compilazione / etc ... per una lingua da " la funzione "scoped piuttosto che" block "scoped?

    
posta tjwrona1992 09.02.2017 - 17:04
fonte

1 risposta

8

In teoria, l'ambito delle funzioni dovrebbe essere più veloce - le variabili sono tipicamente create in uno stack frame, e l'ambito della funzione creerebbe solo quel frame dello stack una volta, mentre l'ambito del blocco dovrebbe aprire in modo ripetitivo un nuovo stack frame in ogni blocco.

In pratica, ci sono molti fatti che invalidano quell'ipotesi iniziale:

  1. Nessun compilatore è obbligato a creare uno stack frame per un blocco solo se viene effettivamente raggiunto un blocco specifico - E la maggior parte dei compilatori lo fa esattamente - Viene creato uno stack frame che contiene spazio per il superset di tutte le variabili che fanno parte di la funzione. Linguaggi come C definiscono solo l'accessibilità in fase di compilazione di una variabile. Quindi, il compilatore deve solo assicurarsi che accedere a una variabile che non è attualmente in ambito è vietato - Non che questa variabile non sia affatto presente . Questa è una regola che può essere applicata in fase di compilazione. Si noti che i buoni compilatori possono persino riutilizzare lo spazio nello stack frame utilizzato da variabili con ambito non sovrapposto e ordinare e consolidare tutte le variabili in uno stack frame per garantire il massimo riutilizzo della memoria.
  2. L'ambito del blocco può consentire un utilizzo migliore delle variabili di registro se il compilatore è abbastanza intelligente e sono disponibili abbastanza registri. Poiché le variabili in un blocco devono avere solo la durata del blocco, possono essere riutilizzate in precedenza.

Quindi, dal punto di vista delle prestazioni, in realtà non vedo vantaggi per entrambi gli approcci. Come sottolineato sopra, è possibile implementare tecnicamente l'ambito della funzione anche se la lingua richiede l'ambito del blocco. Ciò potrebbe sprecare un po 'di memoria, però.

Dal punto di vista di un programmatore, vedo, tuttavia, chiari vantaggi per l'ambito dei blocchi (che potrebbe, tuttavia, essere solo perché sono cresciuto con linguaggi come C e C ++)

    
risposta data 09.02.2017 - 18:18
fonte