#ifdef vs #if-특정 코드 섹션의 컴파일을 활성화 / 비활성화하는 방법으로 더 나은 / 안전한 방법은 무엇입니까? 디버그 인쇄 문이 있습니다. 개인적으로 다음을

이것은 스타일의 문제 일 수 있지만, 개발 팀에 약간의 차이가있어서 다른 사람이이 문제에 대해 아이디어가 있는지 궁금했습니다 …

기본적으로 정상적인 개발 중에 꺼지는 디버그 인쇄 문이 있습니다. 개인적으로 다음을 선호합니다.

//---- SomeSourceFile.cpp ----

#define DEBUG_ENABLED (0)

...

SomeFunction()
{
    int someVariable = 5;

#if(DEBUG_ENABLED)
    printf("Debugging: someVariable == %d", someVariable);
#endif
}

하지만 일부 팀은 다음을 선호합니다.

// #define DEBUG_ENABLED

...

SomeFunction()
{
    int someVariable = 5;

#ifdef DEBUG_ENABLED
    printf("Debugging: someVariable == %d", someVariable);
#endif
}

… 당신에게 더 좋은 방법은 무엇이며 그 이유는 무엇입니까? 내 느낌은 항상 정의 된 것이 있고 다른 정의를 파괴 할 위험이 없기 때문에 첫 번째가 더 안전하다는 것입니다.



답변

#ifdef물론 제 초기 반응은 였지만 #if실제로 이것에 대해 몇 가지 중요한 이점이 있다고 생각합니다 . 그 이유는 다음과 같습니다.

첫째, DEBUG_ENABLED전 처리기 컴파일 된 테스트 에서 사용할 수 있습니다 . 예-종종 디버그가 활성화되었을 때 더 긴 시간 초과를 원하므로을 사용하여 다음 #if과 같이 작성할 수 있습니다.

  DoSomethingSlowWithTimeout(DEBUG_ENABLED? 5000 : 1000);

… 대신에 …

#ifdef DEBUG_MODE
  DoSomethingSlowWithTimeout(5000);
#else
  DoSomethingSlowWithTimeout(1000);
#endif

둘째, #definea에서 전역 상수 로 마이그레이션하려는 경우 더 나은 위치에 있습니다 . #defines는 일반적으로 대부분의 C ++ 프로그래머에게 눈살을 찌푸립니다.

그리고 셋째, 팀에 분열이 있다고 말합니다. 제 생각에는 이것은 다른 회원들이 이미 다른 접근 방식을 채택했으며 표준화해야한다는 것을 의미합니다. 그 판결 #if코드를 사용하는 것을 선호하는 선택 수단되어 #ifdef컴파일 – 그리고 경우에도 실행 -됩니다 DEBUG_ENABLED거짓은. 그리고 그 반대가 아니어야 할 때 생성되는 디버그 출력을 추적하고 제거하는 것이 훨씬 쉽습니다.

아, 그리고 약간의 가독성 포인트. 에서 0/1이 아닌 true / false를 사용할 수 있어야하며 #define값이 단일 어휘 토큰이기 때문에 괄호가 필요하지 않은 한 번입니다.

#define DEBUG_ENABLED true

대신에

#define DEBUG_ENABLED (1)


답변

둘 다 끔찍합니다. 대신 다음을 수행하십시오.

#ifdef DEBUG
#define D(x) do { x } while(0)
#else
#define D(x) do { } while(0)
#endif

그런 다음 디버그 코드가 필요할 때마다 D();. 그리고 당신의 프로그램은의 끔찍한 미로로 오염되지 않습니다 #ifdef.


답변

#ifdef 토큰이 정의되었는지 확인합니다.

#define FOO 0

그때

#ifdef FOO // is true
#if FOO // is false, because it evaluates to "#if 0"


답변

우리는 여러 파일에 걸쳐 이와 동일한 문제가 발생했으며 사람들이 “기능 플래그”파일을 포함하는 것을 잊어 버리는 문제가 항상 있습니다 (코드베이스가 41,000 개 이상이면 쉽게 수행 할 수 있음).

feature.h가있는 경우 :

#ifndef FEATURE_H
#define FEATURE_H

// turn on cool new feature
#define COOL_FEATURE 1

#endif // FEATURE_H

하지만 file.cpp에 헤더 파일을 포함하는 것을 잊었습니다.

#if COOL_FEATURE
    // definitely awesome stuff here...
#endif

그러면 문제가 발생합니다. 컴파일러는이 경우 COOL_FEATURE가 정의되지 않은 “거짓”으로 해석하고 코드를 포함하지 못합니다. 예 gcc는 정의되지 않은 매크로에 오류를 발생시키는 플래그를 지원하지만 대부분의 타사 코드는 기능을 정의하거나 정의하지 않으므로 이식성이 떨어집니다.

우리는이 경우를 수정하고 기능의 상태 인 함수 매크로를 테스트하는 이식 가능한 방법을 채택했습니다.

위의 feature.h를 다음과 같이 변경 한 경우 :

#ifndef FEATURE_H
#define FEATURE_H

// turn on cool new feature
#define COOL_FEATURE() 1

#endif // FEATURE_H

하지만 다시 file.cpp에 헤더 파일을 포함하는 것을 잊었습니다.

#if COOL_FEATURE()
    // definitely awseome stuff here...
#endif

정의되지 않은 함수 매크로를 사용하기 때문에 전처리 기가 오류가 발생했을 것입니다.


답변

조건부 컴파일을 수행하기 위해 #if와 #ifdef는 거의 동일하지만 완전히 그렇지는 않습니다. 조건부 컴파일이 두 기호에 의존하는 경우 #ifdef도 작동하지 않습니다. 예를 들어 두 개의 조건부 컴파일 기호, PRO_VERSION 및 TRIAL_VERSION이 있다고 가정하면 다음과 같을 수 있습니다.

#if defined(PRO_VERSION) && !defined(TRIAL_VERSION)
...
#else
...
#endif

#ifdef를 사용하면 위의 내용이 훨씬 더 복잡해지며 특히 #else 부분이 작동하게됩니다.

조건부 컴파일을 광범위하게 사용하는 코드를 작업하고 있으며 #if와 #ifdef가 혼합되어 있습니다. 간단한 경우에는 # ifdef / # ifndef를 사용하고 둘 이상의 기호가 평가 될 때마다 #if를 사용하는 경향이 있습니다.


답변

전적으로 스타일 문제라고 생각합니다. 둘 다 다른 것에 비해 확실한 이점이 없습니다.

일관성이 특정 선택보다 더 중요하므로 팀과 함께 한 가지 스타일을 선택하고이를 고수하는 것이 좋습니다.


답변

내가 선호하는 것 :

#if defined(DEBUG_ENABLED)

반대 조건을 찾는 코드를 훨씬 쉽게 발견 할 수있게 해주기 때문에 :

#if !defined(DEBUG_ENABLED)

#ifndef(DEBUG_ENABLED)