3

서문에 전달되지 않습니다 :정적 어설 확인하기 위해 컴파일 시간 상수는 매크로

switch(nValue) 
{ 
case X: 
... 
case Y: 
... 
default: 
    ASSERT_FOR_DEFAULT(nValue); 
} 

ASSERT_FOR_DEFAULT은 기본의 경우 "타격보고, A (정의) 주장 대화 상자를 표시하는 매크로입니다 ". 예,이 매크로는 컴파일 타임 어설 션을위한 것이 아니라 런타임 어썰트를위한 것입니다. 하지만, 난 그저 상수 값 (컴파일 타임)을이 매크로에 전달할 수 없다.

문제 :

다음 컴파일에을 실패 :

ASSERT_FOR_DEFAULT(5); 

예, 프로그래머는 다만 switch-casedefault 경우, 어디서나 사용할 수 있습니다. 그는 switch에서 사용되지 않는 표현을 사용할 수도 있습니다. 그러나 그것은 문제가 아닙니다. 그냥 상수가 아닌이 매크로에 전달되어야합니다.

이 매크로에는 아무 것도 중요하지 않지만 단지 ASSERT/assert이라고 가정합니다.

내가 템플릿을 시도, 배열 (같은 strcpy_s), 자신의 구조체 데 YES, NO 종류와 무엇을하지 (그들을 다른 SFINAE/정적-주장! 사용). 그러나 해결책을 찾지 못했습니다!

VC2008을 사용하고 있습니다. 나는 static_assert, decltype 등을 알고 있지만 C++ 0x는 사용할 수 없습니다.


EDIT (솔루션) :이 사랑스러운 제안에 대한 아르네 메츠에

#define STATIC_ASSERT(expr) {int array[!!(expr)]; expr;} 

template <class T> 
bool noConstAllowed(T&); 

int noConstAllowed(...); 

#define ASSERT_FOR_DEFAULT_VALUE(val)    \ 
{             \ 
    STATIC_ASSERT(sizeof(noConstAllowed(val))==sizeof(bool)); \ 
} 

int main() 
{ 
    int test=10; 

    ASSERT_FOR_DEFAULT_VALUE(test); 
    ASSERT_FOR_DEFAULT_VALUE(2); 
    ASSERT_FOR_DEFAULT_VALUE(test+2); //FAILS, but okay for me! 
} 

감사합니다. 나는 그것으로부터 해결책을 이끌어 냈다. noConstAllowed은 모든 T& 유형에 대해 오버로드되며, 상수 값이 전달되면 다른 오버로드가 호출됩니다. 둘 다 반환 유형이 다르므로 크기에 대해 확인합니다. 템플릿 버전에서는 전달 된 변수에 대한 어설 션을 충족하고 상수 또는 표현식에 대해 실패하는 bool을 반환합니다 (반환 유형은 int이므로).

+0

Boost.StaticAssert –

+0

@aleguna, 무의미한 댓글! static-assert를 만드는 방법이 아닌 static-assert에 대한 표현식이 필요합니다. – Ajay

답변

3

리터럴에서 실패해야하는 매개 변수의 주소를 사용하도록 매크로를 다시 정의 할 수 있습니다. 그러나이 변수를 사용하면 상수 변수를 전달할 수 있습니다.

template <class T> void noConstAllowed(T&){}; 
#define ASSERT_FOR_DEFAULT_VALUE(val)    \ 
    {             \ 
    (void*)&(val);   /* no literals*/   \ 
    noConstAllowed(val); /* no constants at all */ \ 
    switchHitDefaultDialog(val, __FILE__, __LINE__); \ 
    } 

난 당신이 FILE 같은 것을 사용한다고 가정

const static int FIVE = 5; 
ASSERT_FOR_DEFAULT(FIVE); // still works. 

매크로 호출에 const가 아닌 참조에 의해 매개 변수를받는 함수를 통과되는 상수의 모든가지 금지 또는 다른 위치 지정 매크로를 사용하거나 함수로 만들 수 있습니다. 너는 두 줄 중 하나만 사용해야한다.

+0

좋은 제안!당신이 준 솔루션은 정적 선언이 아니지만 과부하, 템플릿 및 'noConstAllowed'에 대한 다른 반환 유형과 sizeof로, 나는 그것에 대한 SA를 만들 것입니다. – Ajay

+0

그것을 만들었습니다. 고맙습니다! 내가 찾은 해결책에 대한 편집 된 질문을 확인하십시오. – Ajay

관련 문제