programing

C 컴파일러가 외부 이름에 밑줄을 추가하는 이유는 무엇입니까?

minimums 2023. 7. 2. 19:10
반응형

C 컴파일러가 외부 이름에 밑줄을 추가하는 이유는 무엇입니까?

저는 C에서 너무 오랫동안 일해왔기 때문에 컴파일러가 일반적으로 시작 부분에 밑줄을 추가한다는 사실이 있습니다.extern그냥 이해한 것뿐...하지만 오늘 또 다른 SO 질문은 밑줄이 추가된 진짜 이유에 대해 궁금하게 만들었습니다.위키백과 기사는 다음과 같은 이유가 있다고 주장합니다.

C 컴파일러는 런타임 언어 지원의 기여와의 충돌을 방지하기 위해 모든 외부 범위 프로그램 식별자에 선행 밑줄을 추가하는 것이 일반적이었습니다.

저는 이것에 대해 최소한 진실이 있다고 생각하지만, 또한 모든 외부에 밑줄이 더해진다면 충돌을 예방하는 데 큰 도움이 되지 않기 때문에 질문에 실제로 답하지 않는 것처럼 보입니다.

누가 선행 밑줄의 근거에 대해 좋은 정보를 가지고 있습니까?

에서 사용되는 중 일부입니까?creat()시스템 호출이 'e'로 끝나지 않습니까?일부 플랫폼의 초기 링커는 이름이 6자로 제한되었다고 들었습니다.그렇다면 외부 이름에 밑줄을 추가하는 것은 완전히 미친 생각인 것 같습니다(지금은 5자만 가지고 놀 수 있습니다...).

C 컴파일러는 런타임 언어 지원의 기여와의 충돌을 방지하기 위해 모든 외부 범위 프로그램 식별자에 선행 밑줄을 추가하는 것이 일반적이었습니다.

컴파일러가 런타임 지원을 제공하는 경우 런타임 지원의 몇 가지 외부 식별자에 밑줄을 추가하는 것이 더 타당하다고 생각할 수 있습니다!

C 컴파일러가 처음 등장했을 때, 이러한 플랫폼에서 C로 프로그래밍하는 기본적인 대안은 어셈블리어로 프로그래밍하는 것이었고, 어셈블리어와 C로 작성된 객체 파일을 함께 연결하는 것은 (그리고 여전히) 유용했습니다.따라서 외부 C 식별자에 추가된 선행 밑줄(IMHO)은 자체 어셈블리 코드의 식별자와의 충돌을 방지하기 위한 것이었습니다.

(GCC의 레이블 확장자도 참조하십시오. 앞에 추가된 밑줄은 이름 망글링의 단순한 형태로 간주될 수 있습니다.C++와 같은 더 복잡한 언어는 더 복잡한 이름의 망글링을 사용하지만, 여기서 시작되었습니다.)

만약 c 컴파일러가 항상 모든 기호 앞에 밑줄을 추가한다면, (보통 어셈블리에 쓰여지는) 시작/c-기호 코드는 안전하게 밑줄로 시작하지 않는 레이블과 기호(예: '시작' 기호)를 사용할 수 있습니다.

c 코드에 start() 함수를 작성해도 object/asm 출력에 _start로 생성됩니다.(이 경우 c 코드가 밑줄로 시작하지 않는 기호를 생성할 가능성은 없습니다.) 따라서 스타트업 코더는 각 글로벌 변수/키워드에 대해 발생 가능성이 낮은 기호(예: $_subuse42%$)에 대해 걱정할 필요가 없습니다.

그래서 링커는 이름 충돌에 대해 불평하지 않을 것이고 프로그래머는 행복합니다.:)

다음은 출력 형식에 밑줄을 추가하는 컴파일러의 관행과 다릅니다.

이 관행은 나중에 C 및 C++ 언어 표준의 일부로 성문화되었으며, 구현을 위해 선행 밑줄의 사용이 예약되었습니다.

이는 시스템 라이브러리 및 기타 시스템 구성 요소에 대한 규칙입니다.(그리고 __FILE__ 등의 경우).

(이러한 기호(예: _time)는 생성된 출력에서 두 개의 선행 밑줄(__time)을 생성할 수 있습니다.)

제가 항상 듣기로는 이름 충돌을 피하기 위해서라고 합니다.다른 외부 변수가 아닌 라이브러리를 사용할 때 사용자 코드 변수 이름과 충돌하지 않기를 바랍니다.

주 기능은 실행 파일의 실제 진입점이 아닙니다.정적으로 연결된 일부 파일에는 최종적으로 main을 호출하는 실제 진입점이 있으며 정적으로 연결된 파일은 밑줄로 시작하지 않는 네임스페이스를 소유합니다.내 시스템의 /usr/lib에는 gcrt1.o, crt1.o, dylib1.o 등이 있습니다.각 항목에는 밑줄이 없는 "시작" 기능이 있으며, 이 기능은 최종적으로 "_main" 진입점을 호출합니다.그 파일들을 제외한 나머지 모든 것들은 외부 범위를 가지고 있습니다.역사는 모든 C가 외부로 간주된 프로젝트에서 조립자와 C를 혼합하는 것과 관련이 있습니다.

Wikipedia에서:

C 컴파일러는 런타임 언어 지원의 기여와의 충돌을 방지하기 위해 모든 외부 범위 프로그램 식별자에 선행 밑줄을 추가하는 것이 일반적이었습니다.또한 C/C++ 컴파일러가 번역 프로세스의 일부로 외부 링크에 이름을 도입해야 할 때 이러한 이름은 종종 여러 선행 또는 후행 밑줄의 조합으로 구별되었습니다.

이 관행은 나중에 C 및 C++ 언어 표준의 일부로 성문화되었으며, 구현을 위해 선행 밑줄의 사용이 예약되었습니다.

언급URL : https://stackoverflow.com/questions/2627511/why-do-c-compilers-prepend-underscores-to-external-names

반응형