2011-09-11 10 views
1

내 어설 션 매크로는 다음과 같이이다 : 최적화가 되나요?

#ifdef DEBUG 
#define ASSERT(x) ((void)(!(x) && assert_handler(#x, __FILE__, __LINE__) && (exit(-1), 1))) 
#else 
#define ASSERT(x) ((void)sizeof(x)) 

내가이 더 많거나 적은 방탄라고 생각하지만 부작용에 대한 중요한 기능의 반환 값을 주장의 맥락에서 그것을 많이 사용하는 것으로 보인다 . 내 릴리스에서 내가 컴파일 결국 빌드 경우
ASSERT(fgets(buffer,sizeof(buffer)/sizeof(buffer[0]),file)); 

((void)sizeof(fgets(buffer,sizeof(buffer)/sizeof(buffer[0]),file))); 

이가 완전히 최적화 한 것입니다 기회가 될 것입니다? 나는 그것이 확실하지 않다는 것을 확신한다. (나는 함수를 호출하고있다, fgets), 정확히 그것을 보장하는 조건은 무엇인가? 최적화 프로그램에서 발생할 수있는 부작용이있는 작업이 있습니까?

+12

일반적으로 어설 션을 작성하여 부작용이 없으므로 remoevd가 될 수 있습니다. 'fgets'을 자체 행으로 실행하고 결과를 저장 한 다음,'assert (result! = NULL)'을 사용하십시오. 그런 다음 'x'를 버리지 않는 비 디버그'assert'를 정의하십시오. 아니면 우리가 그곳에있는 동안, stdlib에 '단언'이없는 것입니까? – delnan

+0

좋아요, 그래서 주장은 단순히 부작용에 사용하기위한 것이 아닙니다. 나는 지금 어리 석다. 내 자신의 단언은 디버거에서 매우 쉽게 추적 할 수 있기 때문에 좋은 점이 있습니다. CRT에서 팝업하는 것과는 대조적으로 (프로그램 별 경고? stderr? 수동? 중단 프로그램입니까?) –

+1

"주장하는 쪽 효과 "는 때때로"검증 "이라고 불리므로 매크로에 이름을 붙일 수 있습니다. "assert"는 일반적으로 프로그램 논리의 일부로 요구되지 않는 것으로 이해됩니다. –

답변

3

어설의 일반적인 의미는 밖으로 최적화 할, 그래서 밖으로 최적화되고, 왜 단지

을 할 수 없습니다 당신이 그것을 주장한다면 그 의미에 충실하고

#else 
#define ASSERT(x) 
#endif 

을 수행하는 더 좋을 수도

#else 
#define ASSERT(x) ((void)(x)) 
#endif 

?

+1

단순히 #define ASSERT (x) x'를 사용하지 마십시오. –

+0

@yi_H : 예. 이 방법으로 추측하면 반환 값을 명시 적으로 무시하므로 아무도'if (ASSERT (x)) ... '를 쓸 수 없습니다. –

+1

아이디어의 대부분은 http://cnicholson.net/2009/02/stupid에서 왔습니다. -c-tricks-adventures-in-assert /이 매크로를 사용하는 방법을 재검토해야 할 것 같습니다. 어쩌면 내가 다른 버전의 어설 션을 사용해야합니다. –

4

최적화와 관련이 없습니다. sizeof 표현식을 평가할 때 피연산자가 평가되지 않습니다. 당신은 컴파일러 경고를 생성하지 않고 부작용을 유지하려면 닐 G는 그의 대답에 언급 한 바와 같이 예를 들어,

char func(void) { exit(1); } 

size_t sz = sizeof(func()); 
// same as 
size_t sz = 1; 

, 당신은 void으로 캐스팅 할 수 있습니다.

+1

Sizeof는 컴파일 타임에 반드시 평가되지는 않습니다. 예를 들어,'size_t func (int x) {int a [x]; return sizeof (a); }'. –

+0

감사합니다. C99를 잊어 버렸습니다. –

관련 문제