2014-06-23 3 views
20

extern "C"으로 선언 된 함수가 암시 적으로 또는 명시 적으로 noexcept이되도록하는 표준에서 아무것도 찾을 수 없습니다.C++ 표준에서 C- 링크 기능이`noexcept`라고 명령합니까?

그러나 C 호출 규칙이 예외를 지원할 수 없다는 것이 분명해야합니다. 그렇지 않습니까?

기준에 내가 언급하지 않은 부분이 언급되어 있습니까? 그렇지 않다면 왜 안 되겠습니까? 그것은 단순히 일종의 구현 세부 사항으로 남아 있습니까?

+0

은 C++ 언어 진화에서이 정도의 호환성이 깨지는 것을 상상할 수 있습니까? – Sheen

+2

호환성을 망칠 지 여부는 꽤 의심 스럽습니다. C 함수에서 예외를 누설하는 프로그램은 항상 정의되지 않은 동작을 가질 수 있습니다. – Puppy

+4

관련 http://stackoverflow.com/a/15845731/242520 –

답변

17

"C"연결로 정의 된 함수가 예외를 발생시키지 않는다고 보장 할 수 없다면 말할 수 있습니다. 이 표준은 C++ 프로그램이 "C"언어 링키지가있는 외부 함수를 호출하고 "C"언어 연결이있는 C++로 작성된 함수를 정의 할 수있게합니다. 따라서 C++ 프로그램이 실제로 C++로 작성된 "C"언어 링키지가있는 함수를 호출하는 것을 막을 수있는 방법은 없습니다 (다른 컴파일 단위에서이 작업이 필요하지는 않지만). 그것은 이상한 일이지만, 배제하기가 어렵습니다. 또한 표준에서 이렇게하면 정의되지 않은 동작으로 이어질 것이라고 말합니다 (실제로 Standard는 C++로 작성되지 않은 함수의 정의를 정의 할 수 없기 때문에 이것은 일 뿐이며 형식적으로는 사용되지 않습니다) 사용법 정의되지 않은 동작).

결과적으로 나는 "C"연결이 noexcept을 의미한다고 가정하는 것이 오류라고 생각합니다.

+1

좋은 대답, 당신은 확실히 것들을 올바른 방법으로 단어를 알고 있습니다. – didierc

+2

덜 이상한 상황은 throw하는 C++ 함수를 가리킬 수있는 함수 포인터를 받아들이고 호출하는 C 함수입니다. –

8

음, 나는 extern "C"으로 C 함수가 아니라 C- 링크를 사용한다고 가정합니다. 컴파일러가 C++ name mangling을 수행하는 것을 방지합니다.

자세히 직접 -이 코드를 가정 해 보겠습니다.

// foo.cpp 
extern "C" void foo() 
{ 
    throw 1; 
} 

// bar.cpp 
extern "C" void foo(); 
void bar() 
{ 
    try 
    { 
     foo(); 
    } 
    catch (int) 
    { 
     // yeah! 
    } 
} 
+1

실제로 이름 맹 글링을 막는 것보다 훨씬 더 많은 것이 있습니다. 'extern "C++"void Foo();는'extern "C"void Foo();와 다릅니다. 그들은 서로 다른 ** 유형 **이며 서로 유일한 속성 인 링키지 중 하나입니다. –

+1

나는 그것도 호출 규칙에 영향을 미칠 것이라고 생각했고, 예외는 스택 unwinding이 작동하기위한 특별한 호출 규칙을 요구했다. –