2011-01-14 1 views
27

각 함수 프로토 타입에 속성을두기에 부족하여 gcc가 C 함수가 예외를 전파 할 수 없다는 것을 알리는 방법이 있습니까? 즉, extern "C" 안에 선언 된 모든 함수는 __attribute__((nothrow))이어야합니다. 이상적인 것은 -f 스타일 명령 행 옵션입니다.모든 extern "C"함수가 예외를 전파 할 수 없다고 가정하는 gcc 옵션이 있습니까?

+0

거기에 -fnothrow-opt가 있지만 원하는대로 작동하지 않을 것이라고 생각합니다. 자세한 내용은 http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect-Options.html#C_002b_002b-Dialect-Options을 확인하십시오. – Himanshu

+0

THIS_LINKAGE, THAT_ATTRIBUTES, THE_OTHER_DECORATION 매크로, 거기에 쓰레기 숨기기? 그러한 매크로가 이미 없으면 제어 코드로 읽으면 C로 읽혀도 코드가 불필요하게 엉망이됩니다. –

+2

또한 'extern "C"함수가 예외 (정의 된 동작 포함)를 throw 할 수 없다는 사실이 사실입니까? 그렇다면 GCC가 옵션없이 최적화를 수행하기를 원할 것입니다. 그러나 함수가'extern "C"'로 선언되었지만 C++에서 구현 된 코드와 달리 실제로는 C에서 실제로 호출되지 않는 한 예외를 throw 할 수 있다고 생각합니다. 그것이 합법적인지 아닌지를 기억하십시오. –

답변

4

항상 -fno-exceptions을 사용하면 C++ 컴파일러가 예외 전파 코드를 생성하지 않도록 할 수 있습니다.

+1

나는 C++에서 호출 될 수있는 C로 라이브러리 코드를 작성한다는 관점에서 제 질문을하고 있습니다. GCC가 내 코드를 호출하는 C++ 호출자를 최적화하는 데 도움이되는 gcc 관련 또는 C++ 관련 엉망으로 헤더를 채우고 싶지 않습니다. 나는 오히려 C + +에서 호출하고 불필요한 예외 오버 헤드를 원하지 않는다면 g ++에 그러한 옵션을 전달해야한다는 것을 문서화하고 싶다. 그러한 옵션이 없다면, g ++에서 비 대한 코드를 생성 할 수 있도록하는 것에 만족할 것입니다. –

+9

실제로 실제로 무엇인가를 최적화하고 있습니까? 요즘 예외 처리 설정은 예외 (예외적 인 경우)가 아닌 일반적인 예외 (예외적 인 경우)가 아닌 CPU 시간을 사용하도록 최적화됩니다. 따라서 일반적인 경우에는 실제로 저장할 수있는 것이 없습니다. 호출자가 예외 오버 헤드에 정말로 관심이 있다면이 대답이 올바른 것입니다. 고속 일 필요가있는 모든 코드에 대해 예외를 완전히 해제하십시오. – apenwarr

+1

많은 현대 시스템에서는 예외 지원의 시간 비용이 제로이지만 공간 비용 (디스크의 실행 가능/라이브러리 크기 측면에서)이 엄청 크다는 것에 동의합니다. –

-1

예외가 발생하면 스택을 언 롤하고 기존 스택을 덮어 쓰는 인터럽트를 생성합니다. try/except 구문이있는 지점까지갑니다. 예외를 사용하지 않으면 오버 헤드가 발생하지 않는 것보다이 평균값입니다. 메모리/시간의 오버 헤드 만 try/catch 블록에 있고 throw()에서 스택 언 롤링 만합니다.

c 함수가 예외를 생성하지 않으면 C++에서 try/catch를 호출 할 때 오버 헤드가 공간에서만 발생하지만 예외의 수에는 동일합니다. (그리고이 작은 공간을 일정하게 유지하면서 작은 시간 오버 헤드).

-1

GCC 4.5는 나를 자동으로 최적화하는 것처럼 보입니다. 사실,이 라인은 http://gcc.gnu.org/gcc-4.5/changes.html에서 변경 사항 목록에 나타납니다

  • GCC는 이제 예외 처리 코드를 최적화 할 수 있습니다. 특히 영향을 미치지 않는 것으로 판명 된 정화 지역이 최적화됩니다.
+0

불필요한 코드를 최적화하지만 불필요한 DWARF unwind 정보를 최적화합니까? –

+0

일반적으로 C 함수는 그렇다고 생각했지만 다시주의 깊게 살펴 보았습니다. _inline_ 함수의 경우에만 나타납니다. –

2

사이드 참고 :
가 확실 컴파일러 "모든 funcs 던져 결코"을 말하고 당신이 원하는 정확히 무엇입니까?

extern "C" ... 기능 전파/트리거 예외가 될 수 없습니다. 포인트 경우를 보자

$ ./test 
terminate called after throwing an instance of 'Foo::Away' 
Abort(coredump) 

즉 : 컴파일 및 실행

class Foo { 
public: 
    class Away {}; 
    static void throwaway(void) { throw Away(); } 
} 

extern "C" { 
    void wrap_a_call(void (*wrapped)(void)) { wrapped(); } 
} 

int main(int argc, char **argv) 
{ 
    wrap_a_call(Foo::throwaway); 
    return 0; 
} 

이 생성, 위와 같이 호출하면, 행복하게 예외가 발생하는 C-연동 기능 wrap_a_call()extern "C" (함수 포인터 호출을 통해)에서 "예외 유출"이 발생할 수 있으며 C++의 특정 위치에서 extern "C" 함수를 호출/호출하면 보장이 없음 예외를 호출 할 때 예외가 throw 될 수 없습니다.

+1

예. C 함수가 C++ 예외의 전파와 상호 작용하도록 지정되어 있지 않으면 (C catch를 포착 할 수 없기 때문에 메모리 누수 문제가 있거나 내부의 상태가 longjmp로 인해 손상 될 수 있음을 의미) C++에서 C++ 호출/콜백 경계를 넘어 예외를 전파하는 것은 이미 위험합니다 (C 표준 라이브러리의 함수에서는 정의되지 않은 동작입니다). –

관련 문제