2011-12-29 2 views
2

ASSERT(x) 매크로가 있고 해제 구성에서 주장하는 경우 return을 호출하려고합니다. 이렇게하려면이 ASSERT을 사용하는 함수의 반환 형식을 알아야합니다. 그것을 얻는 방법 (나는 C++03, LLVM GCC 4.2 컴파일러를 다룬다)? 매크로에서 함수의 반환 유형 얻기 (C++)

내 ASSERT 매크로 :

#define ASSERT(x) \ 
    if(!(x)) { 
     LOG ("ASSERT in %s: %d", __FILE__, __LINE__); \ 
     return /*return_type()*/; \ 
    } 

PS : 나는 return 0; 시도 - 컴파일러는 무효 기능에 오류가 표시됩니다 (그리고 나는 복잡한 반환 유형을 시도하지 않은) 경우 return; - void 이외의 기능에 대한 오류 . (업데이트 ...)

내가 werewindle 에 답변 해 드리겠습니다, 니 알라 토텝jdv 얀 드 VAAN 여기. 디버그 구성에는 표준 assert을 사용합니다. 그러나 베타 테스트 후 나는 아직도 최종 고객의 충돌 보고서를 얻고, 대부분의 경우 내 충돌 기능을 변경해야

ASSERT (_some_condition_); 
if (!_some_condition_)  // add this return 
    return _default_value_; 

내 프로그램은 나중에 아마 충돌이 발생할 수 있음을 이해하고 (그렇지 않으면 확실히에서 충돌합니다 현재 기능). 또한 개발은 iPhone 용이므로 앱을 종료 할 수 없습니다 (앱이 프로그래밍 방식으로 종료되지 않을 수도 있음). 그래서 가장 쉬운 방법은 단정이 실패했을 때 "자동 복귀"하는 것입니다.

+0

, 그들은 당신이 상관없이 프로그램이 무슨 버그 실행되지 계속 단지 것을 의미하지 않는다. ** 앱을 제출하기 전에 버그가 없어야 함을 의미합니다 **! –

+0

iPhone - C++이 아닌 Objective-C가 아닙니까? – codeling

+1

예외 사용에 대해 생각해 보셨습니까? 매우 높은 수준의 try-catch 블록을 사용하여 예외 객체에 통합 할 수있는 메시지를 기록 할 수있는 것처럼 보입니다 ('__FILE__' 및'__LINE__'에 의해 주어진 위치와 함께). 당신은 반환 가치에 전혀 관심이없는 것 같은가요? – Andre

답변

4

매크로에서 주변 함수의 반환 유형을 결정할 수 없습니다. 매크로는 전처리기에 의해 확장되며,이 매크로는 이러한 매크로가 발생하는 주변 환경에 대한 정보를 제공하지 않습니다. 이것은 기본적으로 매크로를 검색하고 교체하는 것입니다. 각 반환 유형에 대해 별도의 매크로를 작성해야합니다.

하지만 프로그램을 종료하지 마시고 (즉, exit 함수 호출) 그냥 함수에서 돌아 오는 것은 매우 강력한 오류 처리처럼 보이지 않습니다. 실패한 어설 션은 결국 무언가가 잘못되었거나 (프로그램이 처리하도록 설계되지 않은 상태에 있음을 의미) 발생했을 때만 발생해야하므로 program as soon as possible을 종료하는 것이 가장 좋습니다.

+0

컴파일러 공급 업체가 원한다면 물론 매크로를 추가 할 수 있습니다. 그것은 __LINE__, __FUNC__ 등과 다르지 않습니다. – lkanab

+0

뭔가를 반환하는 한 가지 이유는 가능한 모든 흐름을 살펴 보는 정적 분석 도구입니다. 그들이 돌아 오면 그들은 그 흐름이 끝났음을 알게됩니다. 그들이 출구를 만나는 경우 - 그들은하지 않습니다. – lkanab

0

매크로는 return 값이 아니며, 기능 자체는 아닙니다. 매크로는 사용되는 소스 코드로 대체되므로 매크로가 사용되는 함수에서는 return이됩니다.

매크로에서 return value을 가져 오는 방법은 없습니다.

2

는 어떻게 든 잘못된 프로그램 동작으로 이어질 것입니다 ASSERT의 당신의 변형을 구현하는 경우, 또한 C.

에서 함수 내에서

을 반환 유형을 판별 할 적절한 방법이 없습니다. ASSERT의 주요 아이디어 : 실패하면 프로그램이 정의되지 않은 상태이며 적절한 방법은 지금 중지하는 것입니다. 나는. exit()으로 전화하십시오.

1

C/C++ 전처리 기는 매우 기본이며 코드 분석을 수행 할 수 없습니다. 당신이 할 수있는 일은 반환 형식을 매크로에 전달하는 것입니다.

하지만 내 생각은 다음과 같습니다. 어설 션을 잘못된 방식으로 사용하고 있습니다.코드의 온 전성 검사에만 사용되어야합니다 (프로그래머 때문에 발생할 수있는 오류보다). 모든 주장이 통과되면, 당신은 그것들에 관심을 가질 필요가 없다. 당신은 그것들을 기록 할 필요가 없다.

그리고 그뿐만 아니라 (일반적으로) 최소한 놀람의 요소를 사용해야합니다. ASSERT에 로그인하여 강제로 함수를 반환하도록 하시겠습니까? 나는 안할 거란 걸 알아. 나도 그 응용 프로그램을 완전히 닫으려면 (표준은 assert이 무엇을하는지) 또는 다음에 무슨 일이 일어나는지 결정하게 할 것입니다 (어쩌면 내가 무료로 사용할 포인터가있을 것입니다).

0

템플릿 함수를 사용하면 매크로에서 default (x)를 호출 할 수 있다고 생각합니다.

template<class T> default<T>(T x) { return T(); } 

기본 생성자를 사용하여 모든 작업을 수행합니다. 공백에 대한 특별한 매크로를 작성해야한다고 생각합니다.

템플릿 구문이 올바르다면 C++이 녹슬어지고 있습니다.

+0

'default()'에 전달할 인수는 무엇입니까? – brigadir

+0

반환 값입니다. 매개 변수없는 ctor에서 나오는 T 유형의 기본값을 리턴합니다. –

0

필요에 따라 다른 매크로를 정의 할 수 있습니다.

#define ASSERT(x) \ 
    if(!(x)) { \ 
     LOG ("ASSERT in %s: %d", __FILE__, __LINE__); \ 
     ASSERT_DEFAULT_RETURN(); \ 
    } 

그리고 함수 내부

: 그들은 애플 리케이션 그냥 프로그램 종료 할 수 없다고 말할 때

int foo(){ 
#ifdef ASSERT_DEFAULT_RETURN 
#undef ASSERT_DEFAULT_RETURN 
#endif 
#define ASSERT_DEFAULT_RETURN() return 0 
    // ... 
    ASSERT(some_expression); 
    // ... 
    // cleanup 
#undef ASSERT_DEFAULT_RETURN 
} 
+0

이것은 "섬세한"것은 아니지만 해결책 일 수 있습니다. 최소한의 코딩으로'ASSERT (condition, return_command)'와 같이 보일 것이고 그것을 사용할 수 있습니다 :'ASSERT (x, return 0); – brigadir