Domanda

Si prega di spiegare che cosa è il nome mangling, come funziona, che problema si risolve, e in quali contesti e linguaggi viene utilizzato. Nome strategie di mutilazione (ad esempio quale nome viene scelto dal compilatore e perché) un plus.

È stato utile?

Soluzione

Nel linguaggio di programmazione della vostra scelta, se un identificatore viene esportato da un'unità compilato a parte, ha bisogno di un nome con cui è noto in fase di collegamento. Nome pressare risolve il problema di identificatori di overload in linguaggi di programmazione. (Un identificatore è "sovraccarica", se lo stesso nome è usato in più di un contesto o con più di un significato.)

Alcuni esempi:

  • In C ++, funzione o metodo get possono essere sovraccaricate da diversi tipi.

  • In Ada o Modula-3, funzione get può comparire in più moduli.

tipi multipli e moduli multipli coprono i soliti contesti.

strategie tipiche:

  • Visualizza la mappa ogni tipo in una stringa e utilizzare l'identificatore di alto livello combinati e "tipo string", come il nome del collegamento-tempo. Comune in C ++ (particolarmente facile dal momento che il sovraccarico è consentito solo per le funzioni / metodi e solo su tipi di argomento) e Ada (dove si possono sovraccaricare i tipi di risultato pure).

  • Se un identificatore è utilizzato in più di un modulo o di namespace, unire il nome del modulo con il nome del identificatore, per esempio, invece di List_get List.get.

A seconda di ciò che i personaggi sono legali nei nomi dei collegamenti in tempo, si può avere a che fare ulteriore mutilazione; per esempio, può essere necessario utilizzare la sottolineatura come carattere di 'fuga', in modo da poter distinguere

  • List_my.get -> List__my_get

da

  • List.my_get -> List_my__get

(Certo questo esempio sta raggiungendo, ma come scrittore compilatore, devo garantire che identificatori distinti nel codice sorgente della mappa per i nomi di collegamento in tempo distinti . Questa è tutta la ragione e lo scopo per il nome mutilazione.)

Altri suggerimenti

In poche parole, il nome-mutilazione è un processo mediante il quale compilatori cambia i nomi di identificatori nel codice sorgente al fine di aiutare il linker a disambiguare tra questi identificatori.

Wikipedia ha un bellissimo articolo su questo argomento con diversi grandi esempi.

Nome pressare è un mezzo attraverso il quale compilatori modificare il nome di "compilato" di un oggetto , per renderlo diverso da quello che si è specificato in modo coerente.

Questo permette un linguaggio di programmazione la flessibilità necessaria per fornire lo stesso nome a più, oggetti compilati, e hanno un modo coerente di ricercare l'oggetto appropriato. Per esempio, questo consente a più classi con lo stesso nome di esistere in diversi spazi dei nomi (spesso anteponendo lo spazio dei nomi nel nome della classe, ecc).

operatore e metodo di sovraccarico in molte lingue prendono questo un ulteriore passo avanti - ogni metodo finisce con un nome "storpiato" nella libreria compilata in modo da consentire a più metodi su un tipo di esistere con lo stesso nome

.

In Python, nome-mutilazione è un sistema con il quale le variabili di classe hanno nomi diversi dentro e fuori della classe. Il programmatore "attiva" che mettendo due underscore all'inizio del nome della variabile.

Per esempio, posso definire una semplice classe con alcuni membri:

>>> class Foo(object):
...  def __init__(self):
...   self.x = 3
...   self._y = 4
...   self.__z = 5
... 

In pratica pitone, un nome di variabile inizia con un carattere di sottolineatura è "interno" e non parte dell'interfaccia di classe, e così i programmatori non dovrebbero fare affidamento su di esso. Tuttavia, è ancora visibile:

>>> f = Foo()
>>> f.x
3
>>> f._y
4

A nome della variabile inizia con due underscore è ancora pubblico, ma è il nome-storpiata e quindi più difficile da accedere:

>>> f.__z  
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute '__z'

Se sappiamo come il nome-pressare opere, tuttavia, siamo in grado di ottenere a questo:

>>> f._Foo__z
5

vale a dire. il nome di classe viene anteposto al nome della variabile, con una sottolineatura in più.

Python ha il concetto di rispetto soci 'privati' 'pubblici'; tutto è pubblico. Nome-mutilazione è il segnale più forte possibile, un programmatore può inviare che la variabile non deve essere accessibile dall'esterno della classe.

Fonte: http: //sickprogrammersarea.blogspot. in / 2014/03 / tecnico-intervista-domande-on-c_6.html

La mutilazione dei nomi è il processo utilizzato da compilatori C ++ dare ad ogni funzione nel vostro programma un nome univoco. In C ++, generalmente programmi hanno all'indirizzo almeno alcune funzioni con lo stesso nome. Così nome mangling può essere considerato come un aspetto importante in C ++.

Esempio:             Comunemente, i nomi dei membri sono generati in modo univoco concatenando il nome del membro con quello della classe di esempio data la dichiarazione:

class Class1
 {
        public:
            int val;
            ...
  };

val diventa qualcosa di simile a:

  // a possible member name mangling
     val__11Class1

In Fortran, nome mutilazione è necessario perché la lingua è case insensitive, il che significa che Foo, FOO, Foo, foo ecc .. saranno tutti risolvere per lo stesso simbolo, il cui nome deve essere normalizzata in qualche modo. Diversi compilatori implementano mangling diverso, e questa fonte di grande difficoltà quando si interfaccia con C o oggetti binari compilati con un compilatore diverso. GNU G77 / G95, per esempio, aggiunge sempre un finale sottolineano al nome in minuscolo, a meno che il nome contiene già uno o più caratteri di sottolineatura. In questo caso, vengono aggiunti due sottolineature.

Ad esempio, le seguenti impostazioni

    program test
    end program 

    subroutine foo()
    end subroutine

    subroutine b_ar()
    end subroutine
    subroutine b_a_r()
    end subroutine

Produce i seguenti simboli straziati:

0000000000400806 g     F .text  0000000000000006              b_ar__
0000000000400800 g     F .text  0000000000000006              foo_
000000000040080c g     F .text  0000000000000006              b_a_r__

Al fine di chiamare il codice Fortran dalla C, il nome di routine correttamente mutilato deve essere richiamato (tenendo ovviamente in considerazione le possibili strategie mangling diversi per essere veramente compilatore indipendente). Per chiamare il codice C da Fortran, un'interfaccia C-scritta deve esportare i nomi storpiati correttamente e inoltrare la chiamata alla routine C. Questa interfaccia può quindi essere chiamato da Fortran.

La maggior parte del linguaggio orientato agli oggetti forniscono funzionalità di funzione di sovraccarico. overloading di funzioni Se ogni classe ha molteplici funzioni con gli stessi nomi, ma di tipo e numero poi diversi parametri sono detto di essere sovraccaricato. overloading funzione consente di utilizzare lo stesso nome per funzioni diverse.

Modi per sovraccaricare una funzione

  1. Per cambiare numero di argomenti.
  2. voce dell'Elenco Avendo diversi tipi di argomenti.

Come si ottiene l'overloading di funzioni con nome storpiatura?
C ++ distingue tra funzioni diverse quando si genera il codice oggetto - cambia nome con l'aggiunta di informazioni su argomenti in base al tipo e al numero di argomenti. Questa tecnica di aggiungere informazioni aggiuntive per formare nomi di funzione si chiama Nome Mangling. C ++ standard non specifica alcuna tecnica particolare per il nome mangling, così diversi compilatori possono aggiungere informazioni diverse a funzionare nomi. Ho eseguito il programma di esempio su gcc4.8.4.

class ABC
{       
 public:
  void fun(long a, long b) {}
  void fun(float a, float b) {} 
  void fun(int a, float b) {}   
};
int main()
{
 ABC obj;
 obj.fun(1l,2l);
 obj.fun(1,2.3f);
 obj.fun(3.2f,4.2f);
 return 0;
}

Questo programma hanno 3 funzioni di nome divertirsi con differire sulla base del numero di argomenti e loro tipi. Queste funzioni sono il nome di straziati come di seguito:

ayadav@gateway1:~$ nm ./a.out |grep fun
000000000040058c W _ZN3ABC3funEff
00000000004005a0 W _ZN3ABC3funEif
000000000040057a W _ZN3ABC3funEll
  • ABC è stringa di comando per il nome di classe
  • divertimento è stringa comune per nome della funzione
  • ff due flottante> f tipo di argomenti
  • ll due lungo> argomenti l typeof
  • se primo intero argument-> i e uno flottante> f argomento

Nel momento in cui collegare i redattori sono stati progettati, linguaggi come C, Fortan e COBOL non hanno namespace, classi, membri di classi e le altre cose. La mutilazione dei nomi è necessaria per supportare le funzionalità object-oriented, come quelli con un editor di collegamento che non li supporta. Il fatto che l'editor di collegamento non supporta le funzionalità aggiuntive è spesso mancato; persone significa che dicendo che il nome mangling è necessaria a causa del link editor.

Dal momento che c'è così tanto variazione tra i requisiti linguistici per sostenere che nome mangling fa, non c'è una soluzione semplice al problema di come sostenere in un editor di collegamento. redattori collegamento sono progettati per funzionare con uscita (moduli di oggetto) da una varietà di compilatori e quindi deve avere un modo universale per supportare i nomi.

Tutte le risposte precedenti sono corrette, ma qui è il punto di vista Python / ragionamento con l'esempio.

Definizione

Quando una variabile in una classe ha un prefisso di __ (vale a dire due underscore) e non ha un suffisso di __ (vale a dire due sottolineatura o più) allora è considerato Identficatore privato. Interprete Python converte qualsiasi identificatore privato e storpia il nome di _class__identfier

Example:
MyClassName --> _myClassName
__variable --> __variable

Perché

Questo è necessario perché per evitare problemi che potrebbero essere causati da esigenze imperative attributi. In altre parole, al fine di ignorare, l'interprete Python deve essere in grado di costruire id distinta per il metodo di bambino contro il metodo genitore e utilizzando __ (doppia sottolineatura) consentire python per fare questo. Nell'esempio qui di seguito, senza __help questo codice non avrebbe funzionato.

class Parent:
    def __init__(self):
       self.__help("will take child to school")
    def help(self, activities):
        print("parent",activities)

    __help = help   # private copy of original help() method

class Child(Parent):
    def help(self, activities, days):   # notice this has 3 arguments and overrides the Parent.help()
        self.activities = activities
        self.days = days
        print ("child will do",self.activities, self.days)


# the goal was to extend and override the Parent class to list the child activities too
print ("list parent & child responsibilities")
c = Child()
c.help("laundry","Saturdays")

le risposte qui sono impressionanti così questo è solo un'aggiunta dalla mia piccola esperienza: io uso nome pressare per sapere, quali strumenti (GCC / vs / ...) e come parametri passati nella pila e cosa convenzione di chiamata ho a che fare con, e che in base al nome così per esempio se vedi _main lo so che è un Cdecl lo stesso per gli altri

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top