문제

이름 맹글링이 무엇인지, 어떻게 작동하는지, 어떤 문제를 해결하는지, 어떤 맥락과 언어가 사용되는지 설명해주세요.이름 맹글링 전략(예:컴파일러가 선택한 이름과 이유) 플러스.

도움이 되었습니까?

해결책

선택한 프로그래밍 언어에서 식별자가 별도로 컴파일 된 장치에서 내보내면 링크 시간에 알려진 이름이 필요합니다. 이름 관리 과부하 된 식별자의 문제를 해결합니다 프로그래밍 언어로. (동일한 이름이 둘 이상의 컨텍스트 또는 둘 이상의 의미로 사용되는 경우 식별자는 "과부하"됩니다.)

몇 가지 예 :

  • C ++에서 기능 또는 방법 get 여러 유형으로 과부하 될 수 있습니다.

  • ADA 또는 Modula-3에서 기능 get 여러 모듈에 나타날 수 있습니다.

여러 유형과 여러 모듈이 일반적인 컨텍스트를 포괄합니다.

일반적인 전략 :

  • 각 유형을 문자열에 매핑하고 결합 된 고급 식별자와 "String"을 링크 시간 이름으로 사용하십시오. C ++ (특히 과부하는 기능/메소드 및 인수 유형에 대해서만 허용되기 때문에 특히 쉬운) 및 ADA (결과 유형을 과부하 할 수 있음).

  • 식별자가 둘 이상의 모듈 또는 네임 스페이스에서 사용되는 경우 식별자 이름과 함께 모듈 이름에 가입하십시오. List_get 대신에 List.get.

링크 타임 이름에서 합법적 인 문자에 따라 추가 망설을해야 할 수도 있습니다. 예를 들어 밑줄을 '탈출'문자로 사용해야 할 수도 있으므로 구별 할 수 있습니다.

  • List_my.get -> List__my_get

~에서

  • List.my_get -> List_my__get

(이 예제는 도달하지만 컴파일러 작가로서 소스 코드의 뚜렷한 식별자는 고유 한 링크 타임 이름에 대한 맵. 그것이 이름 망슬링의 모든 이유와 목적입니다.)

다른 팁

간단히 말해서, Name-Mangling은 컴파일러가 소스 코드의 식별자 이름을 변경하여 링커 해당 식별자 간의 명확성.

Wikipedia는이 주제에 대한 훌륭한 기사를 가지고 있습니다 몇 가지 훌륭한 예가 있습니다.

이름 관리 컴파일러가 객체의 "컴파일 된"이름을 수정하여 일관된 방식으로 지정한 것과는 다르게 만들 수있는 수단입니다.

이를 통해 프로그래밍 언어는 여러 개의 컴파일 된 객체에 동일한 이름을 제공 할 수있는 유연성을 허용하며 적절한 객체를 조회하는 일관된 방법을 가질 수 있습니다. 예를 들어, 동일한 이름의 여러 클래스가 다른 네임 스페이스에 존재할 수 있습니다 (종종 네임 스페이스를 클래스 이름 등으로 선물하여).

연산자 및 메소드 오버로드 여러 언어로 한 단계 더 나아갑니다. 각 방법은 컴파일 된 라이브러리의 "Mangled"이름으로 끝납니다.

Python에서 이름 변경(name-mangling)은 클래스 변수가 클래스 내부와 외부에서 서로 다른 이름을 갖는 시스템입니다.프로그래머는 변수 이름 시작 부분에 두 개의 밑줄을 넣어 이를 "활성화"합니다.

예를 들어, 일부 멤버가 포함된 간단한 클래스를 정의할 수 있습니다.

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

Python 실습에서 밑줄로 시작하는 변수 이름은 "내부"이며 클래스 인터페이스의 일부가 아니므로 프로그래머는 이에 의존해서는 안 됩니다.그러나 여전히 표시됩니다.

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

두 개의 밑줄로 시작하는 변수 이름은 여전히 ​​공개되어 있지만 이름이 변조되어 액세스하기가 더 어렵습니다.

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

그러나 이름 변경이 어떻게 작동하는지 안다면 다음과 같이 접근할 수 있습니다.

>>> f._Foo__z
5

즉.클래스 이름은 추가 밑줄과 함께 변수 이름 앞에 추가됩니다.

Python에는 '비공개' 멤버와 '공개' 멤버에 대한 개념이 없습니다.모든 것이 공개됩니다.이름 조작은 클래스 외부에서 변수에 액세스해서는 안 된다는 프로그래머가 보낼 수 있는 가장 강력한 신호입니다.

원천:http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html

이름 Mangling은 C ++ 컴파일러가 사용하는 프로세스는 프로그램의 각 기능에 고유 한 이름을 제공합니다. C ++에서 일반적으로 프로그램은 동일한 이름의 몇 가지 기능을 제공합니다. 따라서 이름 Mangling은 C ++에서 중요한 측면으로 간주 될 수 있습니다.

예시:일반적으로 회원 이름은 멤버의 이름을 클래스의 이름과 연결하여 고유하게 생성됩니다.

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

Val은 다음과 같습니다.

  // a possible member name mangling
     val__11Class1

Fortran에서는 언어가 대소문자를 구분하지 않기 때문에 이름 맹글링이 필요합니다. 이는 Foo, FOO, fOo, foo 등을 의미합니다.모두 동일한 기호로 해석되며 이름은 어떤 방식으로든 정규화되어야 합니다.다양한 컴파일러는 맹글링을 다르게 구현하며, 이는 다른 컴파일러로 컴파일된 C 또는 바이너리 객체와 인터페이스할 때 큰 문제의 원인이 됩니다.예를 들어 GNU g77/g95는 이름에 이미 하나 이상의 밑줄이 포함되어 있지 않는 한 항상 소문자 이름에 후행 밑줄을 추가합니다.이 경우 두 개의 밑줄이 추가됩니다.

예를 들어, 다음 루틴은

    program test
    end program 

    subroutine foo()
    end subroutine

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

다음과 같은 잘못된 기호를 생성합니다.

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

C에서 Fortran 코드를 호출하려면 적절하게 맹글링된 루틴 이름을 호출해야 합니다(분명히 컴파일러에 독립적이기 위해 가능한 다양한 맹글링 전략을 고려해야 합니다).포트란에서 C 코드를 호출하려면 C로 작성된 인터페이스가 적절하게 잘못된 이름을 내보내고 호출을 C 루틴으로 전달해야 합니다.그런 다음 이 인터페이스를 Fortran에서 호출할 수 있습니다.

객체 지향 언어의 대부분은 기능 과부하 기능을 제공합니다.기능 과부하어떤 클래스에도 동일한 이름이지만 다른 매개 변수 유형 및 숫자를 가진 여러 기능이있는 경우 과부하가 발생한다고합니다. 기능 과부하를 사용하면 다른 기능에 동일한 이름을 사용할 수 있습니다.

함수를 과부하시키는 방법

  1. 인수의 수를 변경함으로써.
  2. 다른 유형의 인수를 통해 항목을 나열하십시오.

이름 Mangling으로 기능 과부하가 어떻게 달성됩니까?
C ++ 컴파일러는 객체 코드를 생성 할 때 다른 함수를 구별합니다. 유형 및 인수 수에 따라 인수에 대한 정보를 추가하여 이름을 변경합니다. 기능 이름을 형성하기 위해 추가 정보를 추가하는이 기술을 이름 Mangling이라고합니다. C ++ 표준은 이름 Mangling에 대한 특정 기술을 지정하지 않으므로 다른 컴파일러는 기능 이름에 다른 정보를 추가 할 수 있습니다. 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;
}

이 프로그램에는 인수의 수와 그 유형에 따라 Fun이라는 3 가지 기능이 있습니다. 이 기능 이름은 다음과 같이 엉망입니다.

ayadav@gateway1:~$ nm ./a.out |grep fun
000000000040058c W _ZN3ABC3funEff
00000000004005a0 W _ZN3ABC3funEif
000000000040057a W _ZN3ABC3funEll
  • ABC는 클래스 이름의 명령 문자열입니다
  • 재미는 기능 이름의 일반적인 문자열입니다
  • ff 두 플로트-> f 인수 유형
  • 두 개의 긴 타입 인수
  • 첫 번째 정수 인수 인 경우-> I 및 하나의 float-> f 인수

링크 편집기가 설계되었을 때 C, Fortan 및 Cobol과 같은 언어에는 네임 스페이스, 클래스, 클래스 구성원 및 기타 것들이 없었습니다. 이름 Mangling은 지원하지 않는 링크 편집기와 같은 객체 지향 기능을 지원하려면 필요합니다. 링크 편집기가 추가 기능을 지원하지 않는다는 사실은 종종 누락됩니다. 사람들은 링크 편집기로 인해 Mangling이 필요하다고 말함으로써 그것을 암시합니다.

이름 Mangling이하는 일을 지원하기 위해 언어 요구 사항간에 많은 차이가 있기 때문에 링크 편집기에서이를 지원하는 방법에 대한 간단한 솔루션은 없습니다. 링크 편집기는 다양한 컴파일러의 출력 (객체 모듈)과 함께 작동하도록 설계되었으므로 이름을 지원하는 보편적 인 방법이 있어야합니다.

모든 이전 답변은 정확하지만 여기에는 Python Perspective/Lasoning이 있습니다.

정의

클래스의 변수가 접두사가 __ (즉, 두 밑줄)의 접두사를 가지며 __ (예 : 두 밑줄 이상)의 접미사가 없으면 개인 ID가있는 것으로 간주됩니다. Python 통역사는 모든 개인 식별자를 변환하고 이름을 _class__identfier로 관리합니다.

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

이는 속성을 우선적으로 발생시킬 수있는 문제를 피하기 때문에 필요합니다. 다시 말해, 파이썬 인터프리터는 하위를위한 고유 한 ID를 구축 할 수 있어야하며 __ (이중 밑줄)를 사용하여 Python이이를 수행 할 수 있어야합니다. 아래 예에서 __HELP가 없으면이 코드는 작동하지 않습니다.

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")

여기의 답변은 굉장합니다. 이것은 내 작은 경험의 추가 일뿐입니다. 나는 알기 위해 이름 엉망진창을 사용하고, 어떤 도구 (gcc / vs / ...) 및 매개 변수가 스택에 어떻게 전달되었는지 및 어떤 전화 컨벤션에 전달되었는지 다루고, 그 이름을 기준으로 그 이름을 기준으로 예를 들어 _main 나는 그것이 A라는 것을 안다 Cdecl 다른 사람들도 마찬가지입니다

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top