문제

분명히 (적어도에 따르면 gcc -std=c99) C99는 기능 과부하를 지원하지 않습니다. C에서 새로운 기능을 지원하지 않는 이유는 일반적으로 후진 호환성이지만이 경우 기능 과부하가 뒤로 호환되는 단일 사례를 생각할 수 없습니다. 이 기본 기능을 포함하지 않는 이유는 무엇입니까?

도움이 되었습니까?

해결책

C에서 과부하가 보이지 않는 이유를 이해하려면 C ++로 과부하가 어떻게 처리되는지 더 잘 배우는 데 도움이 될 수 있습니다.

코드를 컴파일 한 후에는 실행 준비가되기 전에 중간체가 객체 코드 연결되어야합니다. 이는 컴파일 된 기능 및 기타 개체의 대략적인 데이터베이스를 바이너리 파일로드/실행할 준비가 된 것으로 변환합니다. 이 추가 단계는 컴파일 된 프로그램이 이용할 수있는 모듈성의 원리 메커니즘이기 때문에 중요합니다. 이 단계에서는 기존 라이브러리에서 코드를 가져 와서 자신의 응용 프로그램 로직과 혼합 할 수 있습니다.

이 단계에서 객체 코드는 모든 기능의 조합과 함께 모든 언어로 작성되었을 수 있습니다. 이를 가능하게하려면 링커가 다른 객체가 언급 할 때 올바른 개체를 선택할 수 있도록 일종의 컨벤션이 필요합니다. 어셈블리 언어로 코딩하는 경우 라벨을 정의 할 때 해당 레이블이 정확히 사용됩니다.

C에서 함수는 링커의 기호 이름이되므로 쓸 때

int main(int argc, char **argv) { return 1; }

컴파일러는 객체 코드의 아카이브를 제공합니다. main.

이것은 잘 작동하지만 링커가 어떤 이름을 사용해야하는지 결정할 수 없기 때문에 동일한 이름을 가진 두 개의 객체를 가질 수 없다는 것을 의미합니다. 링커는 인수 유형에 대해서는 아무것도 모르고 일반적으로 코드에 대해서는 거의 알지 못합니다.

C ++는 추가 정보를 기호 이름으로 직접 인코딩하여이를 해결합니다. 반환 유형과 인수 번호와 유형은 기호 이름에 추가되며 함수 호출 시점에서 그 방식으로 참조됩니다. 링커는 이것이 말할 수있는 한, 함수 호출이 명확하지 않기 때문에 이것이 일어나고 있음을 알 필요가 없습니다.

이것의 단점은 기호 이름이 원래 함수 이름과 같은 것으로 보이지 않는다는 것입니다. 특히, 과부하 된 함수의 이름이 무엇인지 예측하는 것은 거의 불가능합니다. foriegn 코드에 연결하려면 사용할 수 있습니다 extern "C", 이러한 함수가 C 스타일의 기호 이름을 따르는 경우이지만 물론 그러한 함수를 과부하시킬 수는 없습니다.

이러한 차이점은 각 언어의 설계 목표와 관련이 있습니다. C는 이식성과 상호 운용성을 향해 지향적입니다. C는 예측 가능하고 호환되는 일을하는 길을 벗어납니다. C ++는 풍부하고 강력한 시스템을 구축하는 데 더 강력하게 지향적이며 다른 언어와의 상호 작용에 크게 초점을 맞추지 않습니다.

C가 C ++와 상호 작용하기 어려운 코드를 생성하는 기능을 추구 할 가능성은 거의 없다고 생각합니다.

편집하다: 상상력 질문 :

int main (int argc, char ** argv)을 main-int-int-char **와 같은 것으로 해결하면 (그리고 이것은이 부분이 일부였습니다. 표준)? 나는 여기에 문제가 없다. 사실, 이것은 더 많은 정보를 제공하는 것 같습니다 (최적화 등에 사용될 수 있습니다).

이에 답하기 위해 다시 C ++로 돌아가서 과부하를 다루는 방식으로 돌아갑니다. C ++는이 메커니즘을 거의 정확하게 설명했지만 하나의 경고를 사용합니다. C ++는 특정 부분 자체가 어떻게 구현되어야하는지 표준화하지 않은 다음 계속해서 그 생략의 결과 중 일부를 제안합니다. 특히 C ++에는 가상 클래스 멤버가 포함 된 풍부한 유형 시스템이 있습니다. 이 기능을 구현하는 방법은 컴파일러 작가에게 맡겨지며 VTable 해상도의 세부 사항은 기능 서명에 큰 영향을 미칩니다. 이러한 이유로 C ++는 고의적으로 컴파일러 작가가 이름 Mangling을 컴파일러 또는 이러한 주요 기능의 다른 구현으로 동일한 컴파일러에서 상호 호환되지 않도록 제안합니다.

이것은 C ++ 및 C와 같은 고급 언어가 상세한 유형 시스템을 가지고 있지만 하위 레벨 기계 코드는 완전히 타이핑한다는 더 깊은 문제의 증상 일뿐입니다. 임의로 풍부한 유형 시스템은 기계 레벨에서 제공되는 유형의 바이너리 위에 구축됩니다. 링커는 고급 언어에 사용할 수있는 풍부한 유형 정보에 액세스 할 수 없습니다. 링커는 컴파일러에 완전히 의존하여 모든 유형 추상화를 처리하고 적절하게 유형이없는 객체 코드를 생성합니다.

C ++는 Mangled Object 이름에서 필요한 모든 유형 정보를 인코딩하여이를 수행합니다. 그러나 C는 일종의 휴대용 어셈블리 언어가되는 것을 목표로 매우 다른 초점을 가지고 있습니다. C는 선호 된 이름과 결과 객체의 기호 이름 사이에 엄격한 일대일 서신을 갖는 것을 선호합니다. C가 표준화되고 예측 가능한 방식으로라도 이름을 엉망으로 만들면 변경된 이름을 원하는 기호 이름과 일치시키기 위해 큰 노력을 기울여야합니다. 그렇지 않으면 C ++에서와 같이 꺼야합니다. C ++와 달리 C의 유형 시스템은 상당히 작고 간단하기 때문에 이러한 추가 노력은 거의 이점이 없습니다.

동시에, 인수로 취하는 유형에 따라 다른 유사하게 명명 된 C 함수를 정의하는 것은 실제로 표준 관행입니다. 이것의 긴 예를 위해서, OpenGL 네임 스페이스.

다른 팁

C 소스를 컴파일하면 기호 이름이 손상되지 않습니다. 기능 과부하를 소개하는 경우 이름 충돌을 방지하기 위해 이름 Mangling 기술을 제공해야합니다. 결과적으로 C ++와 마찬가지로 컴파일 된 바이너리에 기계 생성 기호 이름이 있습니다.

또한 C는 엄격한 타이핑을 특징으로하지 않습니다. 많은 것들이 C. 과부하 해결 규칙의 복잡성은 그러한 종류의 언어로 혼란을 불러 일으킬 수 있습니다.

저를 포함한 많은 언어 디자이너는 C의 암시 적 프로모션과 기능 과부하의 조합으로 인해 이해하기 어려운 코드를 초래할 수 있다고 생각합니다. 증거는 C ++에 대해 축적 된 지식의 본문을보십시오.

일반적으로 C99는 기존 관행과 크게 호환되는 완만 한 개정이되었습니다. 과부하는 꽤 큰 출발 일 것입니다.

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