2010-06-16 3 views
3

나는 이런 식으로 뭔가 보이는 매크로 VERIFY 추가 일부 Qt는 코드를 사용하고 매크로를 변환 :인라인 함수

#define VERIFY(cond) \ 
{ \ 
    bool ok = cond; \ 
    Q_ASSERT(ok); \ 
} 

코드는 다음 조건 특정되는 동안 사용할 수 실제로 평가, 예를 : 매크로를 싫어

Q_ASSERT(callSomeFunction()); // callSomeFunction not evaluated in release builds! 
VERIFY(callSomeFunction()); // callSomeFunction is always evaluated 

, 내가 대신 인라인 함수로이 설정하고 싶은 :

inline VERIFY(bool condition) 
{ 
    Q_ASSERT(condition); 
} 
,

그러나 릴리스 빌드에서 컴파일러가이 함수에 대한 모든 호출을 최적화 할 것이라고 염려합니다. (Q_ASSERT은 실제로 아무 것도하지 않습니다.) 불필요하게 걱정하거나 최적화 플래그/컴파일러/등에 따라 가능성이 있습니다. .? 그러나, 다시, 컴파일러는 호출을 무시할 수있을만큼 영리 할 수있다

inline VERIFY(bool condition) 
{ 
    condition; 
    Q_ASSERT(condition); 
} 

: 나는 그것을 바꿀 수 같아요.

디버그 빌드와 릴리스 빌드 모두에서이 인라인 대체 안전합니까?

답변

2

인라인 함수의 경우 함수 인수가 평가되지 않는다고 보장 할 수 없습니다.

부작용이 있거나 부작용이있을 수 있으므로 코드를 유지하는 것이 매우 어려울 것입니다. 부작용이있는 경우에는 확실하게 평가가 수행되고 그렇지 않은 경우에는 수행됩니다 컴파일러의 재량에 따라 이렇게하면 느슨하게 제어되는 방식으로 작동하는 프로그램이 남습니다.

매크로에 대한 싫어함을 가지고 있어도 정보에 입각 한 결정을 내려야합니다. 매크로를 사용하면 전 처리기에서 전체 구문을 제거하고 매개 변수를 평가하지 않거나 인라인 함수를 사용하여 컴파일러에서 결정합니다.

+0

나는 위험을 감수하지 않기로 결정했습니다. 감사! – Rob

4

컴파일러가 인라인 VERIFY 함수를 최적화하더라도 bool 인수를 생성하는 함수를 호출하지 않는다는 것을 의미하지는 않습니다.

Q_ASSERT가 릴리스 빌드에서 전달 된 함수를 호출하지 않는 이유는 단순히 함수 호출을 대체하지 않는 매크로이므로 전혀 최적화 할 것이 없다는 것입니다.

0

옵티마이 저는 부작용이있는 코드를 제거하지 않습니다. 그렇지 않으면 프로그램을 최적화하면 작동 방식이 변경됩니다! 이 경우 함수 인수는 전달 된 함수가 완전히 제거 된 경우에도 부작용이있는 경우 (예 : 콘솔에 무언가를 인쇄하는 경우) 항상 평가됩니다. 따라서, 전체 행이 더 동작을 방출 것, 그 부작용이 없기 때문에 (이것은 가정하면 단순히 return 5; 구성) 옵티마이 Return5()에 호출을 생략 할 수

int x = Return5(); 
int y = PrintToConsoleAndReturn5(); 

// x and y never used again 

:

이 코드 상상. 그러나 옵티마이 저는 부작용이 있으므로 PrintToConsoleAndReturn5()에 대한 호출을 생략 할 수 없습니다 (그러나 인라인 할 수 있음). 정수 5를 리턴하지 않고 y에 저장하는 것은 부작용이 없으므로 생략 할 수 있습니다. 간단히 말해 이론은 프로그램의 동작이 동일하거나 최적화되지 않아야하므로 원래 질문에서 OK 여야합니다.

0

최적화 중에 컴파일러는 여전히 코드의 관찰 가능한 효과를 존중해야합니다. 그것은 관찰 할 수있는 경우 callSomeFunction()을 유지해야한다는 것을 의미합니다. (복사본 제거에 주목할 수있는 주변의 개체를 복사 할 때 적용되는 특정 예외가 있습니다. 여기서는 관련이 없습니다).

그러나 릴리스 모드에서는 Q_ASSERT(callSomeFunction());의 최적화가 중요하지 않습니다. 전처리 기가 끝나고 Q_ASSERT 매크로가 확장되었을 때 최적화 할 수있는 것이 남았습니다.

관련 문제