2016-09-16 2 views
29

내 질문은 this one 또는 this one과 비슷하지만 실제로는 동일하지 않으며 두 번째 대답은 받아 들여지지 않았 음을 알고, 전처리 지시문을 추가하는 것이 올바른지 묻기로했습니다. 함수와 비슷한 매크로가 호출됩니까? 다른 매크로가 정의되어있는 경우 어딘가에 특정 차이를 호출 코드에서함수와 같은 매크로에 전 처리기 지시문을 추가하는 것은 잘못 되었습니까?

#define FUNC_MACRO(a, b) // do something with the variables 

과 : I가 시험

// ... 
FUNC_MACRO(aVal 
#ifdef ANOTHER_MACRO 
       + offset 
#endif // ANOTHER_MACRO 
      , bVal); 
// ... 

내 경우

나는 함수 같은 매크로를 내 컴퓨터 (리눅스, gcc 4.8)와 괜찮 았던가 (전처리 지시어의 유무에 상관없이 ANOTHER_MACRO가 정의 된 경우와없는 경우), 그렇게하는 것이 안전 할까?

첫 번째 비슷한 질문의 답에서 16.3/9 단락을 읽었지 만 내 경우에도 마찬가지입니까?

+8

_ "그렇지만 그렇게하는 것이 안전할까요?"_ 정의 _ 안전 _하십시오. –

+4

이 C 또는 C++입니까?C++에는 더 나은 대안이 있습니다. – Bathsheba

+0

괜찮지 만 다른 매크로 관련 내용은 상당히 잘못 될 수 있습니다. C++을 사용한다면이 문제에서 벗어나십시오. – DeiDei

답변

44

C 언어 잎 에서이 같은 정의되지 않은 동작 6.10.3 매크로 교체, ¶11 :

달리 전처리 지침 역할을 할 인수 목록에서 전처리 토큰의 시퀀스가있는 경우

, 동작은 정의되지 않습니다.

실제로 그렇게하는 것은 잘못되었습니다.

GCC와 다른 인기있는 컴파일러는이를 포착하지 않기 때문에 많은 언어 사용자가이를 인식하지 못할 수 있습니다. 내 코드 중 일부가 PCC에서 컴파일하지 못했을 때 (그리고 신속하게 내 코드에서 버그 수정)이 문제가 발생했습니다.

업데이트 : PJTraill은 매크로 확장에서 전 처리기 지시문을 사용하는 것이 "오해의 소지가 있거나 의미가없는"경우에 대해 주석에서 질문했습니다.

foo(a, b, 
#ifdef BAR 
     c); 
#else 
     d); 
#endif 

나는 언어가 매크로 확장 내부 균형 처리기 조건문에 문제가 없는지를 지정하는 것이 타당했을 것이다 있는지 모르겠지만, 난 당신이 문제에 실행 거라고 생각 : 여기에 명백한 일이다 그것들이 처리되어야하는 순서로 모호함이있다.

+2

당신은 이미 알고있는 언어에 대한 답변을 가지고 있습니다. 알고 계셔도 좋습니다만, Microsoft가 ASCII 및 유니 코드 또는 "일반"및 "보안"방식에서 작동하도록 메서드를 "조정"해야하는 빈도를 감안할 때, , 등, 나는 그들의 컴파일러가 실제로 이것을 지원하기를 바랄 것이다. IMHO, 매크로의 요점은 매크로를 알 필요가 없다는 것입니다. –

+1

결론은 확실하지만, 언뜻보기에 코드를 직관적으로 합리적인 것으로 해석합니다. 오해의 소지가 있거나 무의미한 경우로 언어 표준에 동기 부여 할 수 있습니까? – PJTraill

+0

분명히, '# if'가 매크로의 "내부"에서 평가되도록 의도 된 시나리오를 명시 적으로 설정할 수는 있지만, 가장 이해할 수있는 행동은 항상 이전의 사전 처리 토큰과 같은 매크로 전개. –

20

대신 다음 중 하나를 수행 하시겠습니까?

#ifdef ANOTHER_MACRO 
FUNC_MACRO(aVal + offset, bVal); 
#else 
FUNC_MACRO(aVal, bVal); 
#endif 

편집 : 코멘트에 의해 제기 주소 우려; 나는 OP의 방법이 이라면 구체적으로 (나는 다른 답변이 그것을 커버한다고 생각한다)이 맞는지 모른다. 그러나 간결함과 명확성은 C로 코딩 할 때 매우 중요하게 여겨지는 두 가지 측면입니다.

이렇게 나는 OP와 같은 상황을 약간 재검토하여 더 나은 방법을 찾고 싶습니다. 위에 제안했다. 나는 OP가 triviallised 예제를 사용했을지도 모른다고 생각하지만 일반적으로 대부분의 C 상황에서 뭔가가 지나치게 복잡 해지거나 무언가를하려고 시도 할 때 언어가 허용해야하는 것처럼 보이지 않는다면 필요한 것을 성취 할 수있는 더 좋은 방법이 있다는 것을 알게됩니다. .

+2

그건 해결책이지 답이 아닙니다. 확실히 작동하지 않는 다른 것을 피하기 위해 노력하지만 실제로는 알지 못합니다. 그는 확실히 알고 싶어합니다. –

+4

@ Peregring-lk 틀렸어. [답변 방법] (http://stackoverflow.com/help/how-to-answer)은 대체 솔루션을 제공하는 답변을 명시 적으로 환영합니다. "대답은 '하지 마라.'하지만 '시도 이 대신에. " 위대한 답이 왜 대안과 함께 나쁜지를 설명 할 것이기 때문에 이것은 최선의 해답은 아니지만 그 질문에 대한 정당한 대답입니다. – jpmc26

관련 문제