Come vengono utilizzati gli spazi dei nomi nello stack durante la ricerca dell'ambito?

3

Sto seguendo un corso di linguaggi di programmazione comparativo e ho appreso le basi di base degli ambiti variabili rispetto ai frame di stack - ad es. collegamenti statici e dinamici, offset, ecc. come in l'immagine nella parte inferiore di questa pagina per esempio.

Nei nostri testi (due: Comprensione linguaggi di programmazione di Ben-Ari e Concetti di linguaggi di programmazione di Sebesta, più la mia copia di Pragmatica del linguaggio di programmazione da Scott) ci sono discussioni sugli spazi dei nomi ma nessuna spiegazione che ho visto degli spazi dei nomi in relazione al frame dello stack.

In che modo gli spazi dei nomi influenzano il processo di ricerca delle variabili nello stack?

È corretto dire che quando un record di attivazione viene istanziato nello stack e collegato al nome completo (namespace.variableName), e non solo al nome come detto nei nostri testi? In caso contrario, non vedo come si possa disambiguare lo stesso identificatore da due spazi dei nomi nell'ambito corrente.

    
posta Dave 04.12.2016 - 05:10
fonte

3 risposte

2

Stai parlando dell'accesso alle variabili locali nell'ambito, a causa dell'esempio a cui ti stai riferendo e perché parli di attivazioni, che è il luogo in cui vivono le variabili locali.

Non c'è nulla che io sappia sull'accesso qualificato a namespace alle variabili locali.

Le variabili locali hanno un ambito per il metodo di contenimento, ma fondamentalmente non partecipano agli spazi dei nomi - non c'è modo di usare un'espressione qualificata nello spazio dei nomi per raggiungere una variabile locale (del metodo) nelle lingue che conosco.

Le variabili locali sono in metodi; i metodi sono in classi.

Le classi si trovano in (altre) classi o spazi dei nomi e gli spazi dei nomi sono root o in altri spazi dei nomi.

Possiamo costruire un'espressione a partire da uno spazio dei nomi per raggiungere / identificare una classe. E possiamo estendere tale espressione per raggiungere / identificare un metodo (statico), ma non possiamo estendere ulteriormente tale espressione per raggiungere una variabile locale in quel metodo.

Le variabili locali possono essere raggiunte solo se si trovano nell'ambito di applicazione e quindi vengono indicate solo con un nome semplice. Lo spazio dei nomi associato è compreso dal contesto del metodo (in fase di compilazione), anche se sostanzialmente non ha alcuna influenza sull'individuazione delle variabili locali, che viene eseguita dall'ambito dell'ambito anziché dai namespace.

    
risposta data 04.12.2016 - 07:31
fonte
2

I frame di stack sono usati per memorizzare variabili locali (variabili dichiarate all'interno di una funzione). In molte lingue, non è significativo parlare del "nome completo" di una variabile locale.

Al contrario, namespace, pacchetti o moduli vengono utilizzati per organizzare i simboli globali. Questi simboli possono fare riferimento a funzioni di livello superiore o variabili globali oa concetti che non sono rappresentati direttamente nella memoria. Gli accessi a questi simboli non vengono quindi compilati in quanto la memoria viene letta in relazione al puntatore dello stack.

È anche importante notare che i frame stack non contengono il nome dei simboli che contengono. Se un frame dello stack "memorizza una variabile x ", significa semplicemente che riserva memoria a un offset di puntatore dello stack noto in fase di compilazione per il valore di tale variabile. Poiché tutti gli accessi sono eseguiti tramite l'offset e non il nome, il nome è sconosciuto in fase di esecuzione (a meno che non si compili con i simboli di debug attivati).

Con le funzioni annidate, potremmo voler fare riferimento ai simboli di una funzione di inclusione, ad es.

function f(x) {
  return function g(y) { return x + y; }
}

Qui, all'interno g() il simbolo x fa riferimento all'ambito esterno. Questo può essere fatto con link statici: c'è un puntatore dal frame dello stack di g() allo stack frame di f() . In pseudo-C, y verrebbe compilato come stack_frame->y , ma x come stack_frame->enclosing_scope->x .

La parte difficile con le funzioni annidate non sta attraversando la catena di ambito, ma assicurandosi che tutti gli ambiti accessibili durino quanto ogni riferimento a una funzione nidificata. Se un riferimento a una funzione nidificata può lasciare la funzione di inclusione, questo implica necessariamente la garbage collection.

Se l'ambito che racchiude ha una variabile con lo stesso nome di un ambito interno, l'ambito interno ombreggia la variabile esterna:

function f(x) {
  return function g(x) { return x; } // x always refers to g()'s x
}

Nella maggior parte delle lingue, la variabile f() di x è completamente inaccessibile da g() . Eccezioni alla regola:

  • Il nonlocal di Python è simile, ma in realtà si limita ad aliasare una variabile esterna nello scope nidificato. Non consente di disambiguare le variabili interne e quelle ombreggiate.

  • Lo pseudo-namespace% perOUTER di Perl6 ci consente di accedere alle variabili ombreggiate:

    my $x = 5;
    {
       my $x = 6;
       say $x;          #=> 6
       say $OUTER::x    #=> 5
    }
    

    Lo spazio dei nomi OUTER non è uno spazio dei nomi globale, ma piuttosto un modo per aumentare il processo di ricerca delle variabili.

risposta data 04.12.2016 - 07:45
fonte
1

How do namespaces affect the process of variable lookup in the stack?

Non lo fanno, almeno non in C #.

In C #, gli spazi dei nomi sono una comodità del codice sorgente; scompaiono completamente quando si compila. In sostanza, tutti i riferimenti sono pienamente qualificati in fase di compilazione. Quindi gli spazi dei nomi non hanno alcun effetto sulla ricerca di variabili nello stack di qualsiasi tipo.

Il tuo chilometraggio può variare in altre lingue.

    
risposta data 04.12.2016 - 05:23
fonte