태그 보관물: portability

portability

C는 왜 C ++가 부족한 언어 ‘바인딩’을 제공합니까? 걸렸지 만

최근에 C를 C ++보다 언제 사용할 것인지 궁금해 하고 있었습니까? 다행스럽게도 누군가 이미 저를 이겼고 시간이 걸렸지 만 그 질문에 대한 모든 답변과 의견을 요약 할 수있었습니다.

그러나 해당 게시물의 한 항목은 어떤 종류의 예나 확인이나 설명없이 계속해서 반복해서 다루어집니다.

“C 코드는 라이브러리에 여러 언어 바인딩을 원할 때 유용합니다.”

그것은 역설이다. 몇몇 사람들은 C ++에서 (일부 extern기능을 통해 ) 다중 언어 바인딩이 가능하다는 것을 지적 하지만 그럼에도 불구하고 그 게시물을 완전히 읽으면 C가 이식성 / 언어 바인딩에 이상적이라는 것이 분명합니다. 내 질문은 : 왜?

누군가 C 언어로 라이브러리를 작성하면 다른 언어로 쉽게 바인딩하거나 이식 할 수있는 구체적인 이유를 알려줄 수 있습니까?



답변

C는 훨씬 더 간단한 인터페이스를 가지고 있으며, 소스 코드 인터페이스를 이진 인터페이스로 변환하는 규칙은 간단하게 바인딩 할 외부 인터페이스를 생성하는 데 매우 간단합니다. 반면 C ++은 매우 복잡한 인터페이스를 가지고 있으며 ABI 바인딩 규칙은 공식적으로나 실제로 표준화되지 않았습니다. 이는 모든 플랫폼의 모든 언어에 대한 거의 모든 컴파일러가 외부 C 인터페이스에 바인딩되어 정확히 무엇을 알 수 있는지를 의미하지만 C ++ 인터페이스의 경우 규칙이 어떤 컴파일러, 버전 및 버전에 따라 변경되기 때문에 본질적으로 불가능합니다. C ++ 코드가 내장 된 플랫폼.

C에는 표준 이진 언어 구현 규칙이 없지만 훨씬 간단합니다. 실제로 컴파일러는 동일한 규칙을 사용합니다. C ++ 코드를 디버깅하기 어려운 또 다른 이유는 위에서 언급 한 복잡한 문법인데, 디버거는 종종 많은 언어 기능 (템플릿에 중단 점 배치, 데이터 표시 창에서 포인터 캐스팅 명령 구문 분석 등)을 처리 할 수 ​​없기 때문입니다.

표준 ABI (애플리케이션 바이너리 인터페이스)가 없으면 또 다른 결과가 발생합니다. 동일한 툴과 빌드 옵션으로 컴파일하지 않으면 사용자 코드가 작동하지 않기 때문에 다른 팀 / 고객에게 C ++ 인터페이스를 제공하는 것은 실용적이지 않습니다. 우리는 이미이 문제의 또 다른 원인 인 컴파일 시간 캡슐화가 없기 때문에 바이너리 인터페이스의 불안정성을 보았습니다.

결함이있는 C ++


답변

다른 언어로 말하는 사람과 의사 소통을하려는 경우, 셰익스피어 영어보다 피진 이 더 쉽습니다.

함수 호출, 포인터, NULL로 끝나는 문자열과 같은 C의 개념은 매우 간단하므로 다른 언어는 C 함수를 호출하기에 충분할 정도로 쉽게 구현할 수 있습니다. 역사적 이유로, 많은 다른 언어가 C로 구현되어 C 함수 호출이 훨씬 쉬워졌습니다.

C ++은 상속과 vtable, 액세스 수정자를 가진 클래스를 추가합니다. 스택 해제 및 제어 흐름 변경과 함께 예외; 템플릿. 이 모든 것이 다른 언어에서 C ++ 바인딩을 사용하기 어렵게 만듭니다. 기껏해야 구현할 “접착제”또는 상호 운용성 코드가 더 많으며 최악의 경우 개념이 직접 변환되지 않습니다 (클래스 모델의 차이, 예외 처리, 기타.). 특히 템플릿의 경우 단순히 사용 (인스턴스화)하면 일반적으로 C ++ 컴파일러를 사용하는 컴파일 단계가 필요합니다.이 단계 는 다른 환경에서 사용하기 가 상당히 복잡합니다.

이 모든 것을 말하면 C ++ 라이브러리에서 다른 언어로 바인딩을 제공하는 데 어려움을 과장 할 수 있습니다.

  • C ++ 바인딩은 기꺼이 작업하려는 경우 C와 마찬가지로 호환 될 수 있습니다. @DeadMG가 지적했듯이 C ++은을 지원 extern "C"하므로 C 스타일 라이브러리 (C 바인딩의 단순성과 호환성을 모두 갖춘)를 C ++ 라이브러리에서 내보낼 수 있습니다 (C ++ 관련 기능을 노출 할 수 없다는 제한이 있음) .
  • C ++ 언어 바인딩에 대한 또 다른 일반적인 반대 의견은 C ++에 대한 ABI 안정성이 부족하다는 것입니다. C ++ ABI는 C ABI보다 표준화 수준이 낮지 만 표준 및 사실상의 표준 (Itanium C ++ ABI는 OS X 에서도 사용됨 ; Linux 의 GCC의 사실상 표준 )이 있습니다. Windows는 더 나쁘지만 Windows에서도 Visual C ++ 버전 하나를 유지하는 것이 좋습니다.

답변

C는 여전히 가장 오래된 언어 중 하나입니다. ABI는 단순하며 오늘날에도 여전히 사용되고있는 거의 모든 운영 체제가 여기에 작성되었습니다 . 이러한 OS 중 일부는 C # / .NET 또는 맨 위에있는 항목을 추가했을 수 있지만 아래에서 C에서는 매우 가파 릅니다.

즉 , OS에서 제공하는 기능 을 사용 하려면 사실상 모든 프로그래밍 언어가 C 라이브러리와 인터페이스 할 수있는 방법이 필요했습니다 . Perl, Java, C ++는 모두 기본적으로 “토론 C”를 할 수있는 방법을 제공합니다. 왜냐하면 모든 휠을 재발 명하고 싶지 않다면 필요했습니다.

이것은 C를 프로그래밍 언어의 라틴어로 만듭니다. (비유가 나오기 전에 몇 년 동안 인터넷이 “프로 게밍 언어의 영어”여야합니까?)


C로 라이브러리를 작성하는 경우 C 호환 인터페이스가 무료로 제공됩니다. C ++로 라이브러리를 작성하는 경우 언급 한대로 선언을 통해 C 바인딩을 얻을 수 있습니다extern "C" .

그러나 C로 표현할 수있는 기능에 대해서만 바인딩을 얻을 수 있습니다 .

따라서 라이브러리 API는 사용할 수 없습니다 …

  • 템플릿,
  • 클래스,
  • 예외
  • 객체를 가져 오거나 반환 하는 함수

간단한 예를 들어, 내 보낸 함수 배열 ( ) 대신 (또는 그 문제) 배열을 가져 오고 반환 하도록해야합니다 .[]std::vectorstd::string

따라서 C ++이 라이브러리 클라이언트에 제공해야하는 장점을 제공 할 수 없을 뿐만 아니라 라이브러리 API를 C ++에서 “C 호환 가능”( ” extern "C") 으로”번역 “하기 위해 추가 노력을 기울여야합니다 .

포인트가 이유입니다 수있는 C 라이브러리를 구현하기위한 더 나은 선택이라고 할. 개인적으로 저는 C ++의 이점이 여전히 extern "C"API에 필요한 노력보다 중요하다고 생각 하지만 그것은 저뿐입니다.


답변

다른 답변이 이미 제공 한 세부 정보를 남기십시오.

많은 언어가 C 바인딩을 제공하는 이유는 모든 * nix 및 Windows 운영 체제가 C 인터페이스를 통해 대부분의 OS API를 노출하기 때문입니다. 따라서 언어 구현은 이미 주요 Oses에서 실행될 수 있도록 C와 인터페이스해야합니다. 따라서 언어 자체에서 C 인터페이스와 직접 통신하는 것도 간단합니다.


답변

이유가 없습니다. 표현하려는 의미가 기본적으로 C와 호환되고 템플릿과 같은 것이 아니라면 구현이 C로 작성된 경우 더 쉽게 바인딩 할 수있는 이유가 없습니다. 사실상 C 인터페이스가 될 수 있다는 것은 정의의한 것입니다. 다른 언어로 된 구현을 포함하여 이진 계약을 충족시킬 수있는 모든 구현으로 채워집니다. 이러한 방식으로 작동 할 수있는 C 이진 계약을 구현할 수있는 C ++ 이외의 언어가 있습니다.

실제로 의미있는 것은 실제로 유용한 시맨틱 스나 공룡 시대에 머무를 이유를 선택하기 위해 필사적으로 노력하는 새로운 언어 나 아이디어를 배우기를 원하지 않는 사람들입니다.


답변

다른 언어와 인터페이스 할 때 두 가지 주요 축이 있습니다.

  • 인터페이스가 수행 할 수있는 개념 : 단지 가치? 참조? 제네릭?
  • 인터페이스가 “바이너리”(ABI)로 구현되는 방법

C는이 두 가지 측면에서 C ++보다 장점이 있습니다.

  • C는 대부분의 다른 모든 언어로 나타나는 대부분 간단한 개념을 가지고 있습니다 1
  • C 바이너리의 ABI는 OS 2에 의해 결정됩니다.

이제 대부분의 언어가 C와 비슷한 개념을 갖는가는 “단순”또는 “기존”때문일 수 있습니다. 중요한 것은 요점은 그들이하는 것입니다.

반대로 C ++에는 복잡한 개념이 있으며 ABI는 각 컴파일러에 의해 결정됩니다 (많은 사람들이 Windows를 제외하고 Itanimum ABI를 준수하지만 …). 실제로 Herb Sutter는이 문제를 부분적으로 해결하기 위해 OS별로 C ++ ABI를 수정하도록 제안했습니다. 또한 C ++ FFI가 가능하다는 것을 알아야합니다 .D는 3을 시도하고 있습니다.

1 variadics ( ...)를 제외하고 는 단순하지 않습니다

2 C에는 표준 ABI가 있습니까?

3 D를 레거시 C ++ 코드와 인터페이스


답변

기본적으로 ABI 표준화로 귀결됩니다. C 나 C ++에는 다른 언어로 작성된 이진 파일 간 인터페이스에 사용할 수있는 표준화 된 ABI가 없지만 C는 사실상의 표준이되었으며 모든 사람은이를 알고 있으며 다른 모든 사람은 언어와 관련하여 동일하고 간단한 규칙을 사용할 수 있습니다. 타입과 함수 호출.

C ++은 표준 ABI를 가질 수 있지만 Stroustrup은 자신이 필요하지 않다고 말했다. 그는 또한 컴파일러 작성자들로부터 합의를 얻는 것이 어려울 것이라고 말했다 (물론 C ++ 표준위원회는 기존의 것과 비슷한 ABI를 발행하고 컴파일러 작성자는 단순히 바이너리와 호환되지 않는 다음 버전의 컴파일러를 변경하게 될 것이라고 의심한다) 어쨌든 이전 버전의 컴파일러로 빌드되었습니다. 새로운 Sun 컴파일러로 라이브러리를 다시 컴파일하고 이전 컴파일러와 작동하지 않는 것을 발견했습니다)

일부 회사는 표준 ABI를 사용하기로 옮겼으며 Microsoft는 90 년대에 COM 방식으로이 프로세스를 시작했으며 오늘날에는이를 WinRT ABI로 구체화했습니다 (다른 WinRT와 혼동하지 말 것). C #으로 작성된 프로그램이 C 또는 C ++로 작성된 라이브러리와 통신 할 수 있도록하는 테이블 OS 유형) (예 : Microsoft의 자체 OS 계층은 C ++로 작성되고 WinRT를 사용하여 노출되며 OS 런타임 루틴을 호출 할 때 C # 응용 프로그램에서 사용됨)

표준기구가이 상황을 해결하지 않으면 누구나 할 수있는 일이 많지 않습니다. Microsoft는 분명히 그 가치를보고 플랫폼에 맞게이를 해결하기위한 조치를 취했습니다.

따라서 실제로 C 언어 바인딩을 제공 하지 않습니다 . 아무도 듣고 듣지도 않고 일어납니다.