2009-02-27 4 views
114

C++, 그리고 __FUNCTION__ 사용하여 C++ 컴파일러는 로깅 및 디버깅을 위해 __FILE__, __LINE____FUNCTION__를 사용하기 위해 특별한 이유 하지이 그들을 지원하는 것을 가정하면?__FILE__은, __LINE__

나는 사용자에게 오해의 소지가있는 데이터 (예 : 잘못된 행 번호 또는 기능을 최적화 결과로보고하는 것)를 제공하거나 결과로 실적을 저하시키는 것과 관련이 있습니다.

기본적으로, -__FILE__, __LINE____FUNCTION__ 항상이 옳은 일을 믿을 수 있습니까?

+0

__LINE__은 올바른 일을해야합니다. 나는 그것을 __PRETTY_FUNCTION__을 포함하여 광범위하게 사용했다. ...하지만 ... 글쎄, 지금은 __LINE__이있는 코드를보고 있습니다. 아마도 try/catch 예외 처리를위한 catch 블록에 있기 때문일 수 있습니다. –

+2

관련 : [gcc reference for predefined macros] (http://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html) –

답변

140

__FUNCTION__이 비표준 인 경우 C99/C++ 11에 __func__이 존재합니다. 나머지는 (__LINE____FILE__) 괜찮습니다.

항상 올바른 파일과 행을보고합니다 (그리고 __FUNCTION__/__func__을 사용하도록 선택하면 작동합니다). 최적화는 컴파일 타임 매크로 확장이기 때문에 비 요소입니다. 절대 어떤 식 으로든 성능을 향상시킵니다.

+2

'__func__'은 C++에서 문제가되는 종류입니다. C99에서는 기본 인수 등에 대해 말하지 않으며, C++에서'__func__'가 어떻게 동작해야하는지 명확하지 않습니다. – wilhelmtell

+3

@thr : 좋은 지적을하는 동안. C++이 아니라 c99에'__func__'이 존재한다는 것이 확실합니다. 어쨌든, 나는 C++에서 '__func__'를 합리적인 방식으로 구현하면 이름이 엉망이 될 것이라고 생각합니다. 필자는 컴파일러 작성자가 아니기 때문에 제 전화는 아닙니다. –

+0

'__FUNCTION__'을 지원하지 않는 컴파일러는 무엇입니까? 최근의 gcc를 제외한 어떤 컴파일러가 이것을 매크로가 아닌 변수로 취급합니까? – basin

7

개인적으로 저는 이러한 것들을 디버깅 메시지 이외에 사용하는 것을 꺼립니다. 나는 해냈지만 고객이나 최종 사용자에게 그러한 종류의 정보를 보여주지 않으려 고 노력합니다. 내 고객은 엔지니어가 아니며 때로는 컴퓨터에 정통하지도 않습니다. 내가 콘솔에이 정보를 기록 할 수도 있지만, 말했듯이 마지 못해 디버그 빌드 나 내부 도구를 제외하고는. 당신이 가지고있는 고객층에 달려 있다고 생각합니다.

+21

"콘솔에이 정보를 기록 할 수 있습니다."- 또는 더 나은 방법은 : 파일에 기록하여 문제가 발생하면 고객에게 보내달라고 요청할 수 있습니다. – Christoph

30

드문 경우지만 __LINE__에 의해 주어진 행을 다른 것으로 변경하는 것이 유용 할 수 있습니다. 필자는 GNU configure가 원래 소스 파일에 나타나지 않는 행 사이에 부두를 삽입 한 후 적절한 행 번호를보고하는 일부 테스트를 수행한다는 것을 알았습니다. 예를 들어 :

#line 100 

는 다음과 같은 라인이 __LINE__ (100)와 함께 당신은 선택적으로 그것은 단지 거의 유용하지 않는 새 파일 이름

#line 100 "file.c" 

을 추가 할 수 있습니다 시작 할 것입니다. 그러나 그것이 필요한 경우, 제가 아는 대안이 없습니다. 사실, 선 대신 매크로를 사용하여 위의 두 가지 형식 중 하나를 가져와야합니다. 부스트 전처리 라이브러리를 사용하면 (50)에 의해 현재 행을 증가 할 수 있습니다

#line BOOST_PP_ADD(__LINE__, 50) 

난 당신이 __LINE____FILE__의 사용에 대해 질문 이후는, 그것을 언급하는 것이 유용 생각했다. 하나는 결코 밖으로 충분히 놀라움을 얻을 수 없습니다 C++ :

편집 : @ 조나단 레플러는 의견에 좀 더 좋은 사용 사례를 제공

는 # 라인 덤비는 사전 프로세서에 매우 유용하다 사용자의 소스 파일에 따라 사용자의 C 코드에보고 된 오류를 유지하려고합니다. Yacc, Lex, (저에게 가정에서 더 많이) ESQL/C 전 처리기가 그렇게합니다.

22

FYI : g ++은 비표준 __PRETTY_FUNCTION__ 매크로를 제공합니다. 지금까지는 C99에 대해 몰랐습니다. __func__ (감사합니다! Evan!).나는 그것이 여분의 클래스 스코핑을 위해 사용할 수있을 때 여전히 __PRETTY_FUNCTION__을 선호한다고 생각한다.

PS :

static string getScopedClassMethod(string thePrettyFunction) 
{ 
    size_t index = thePrettyFunction . find("("); 
    if (index == string::npos) 
    return thePrettyFunction; /* Degenerate case */ 

    thePrettyFunction . erase(index); 

    index = thePrettyFunction . rfind(" "); 
    if (index == string::npos) 
    return thePrettyFunction; /* Degenerate case */ 

    thePrettyFunction . erase(0, index + 1); 

    return thePrettyFunction; /* The scoped class name. */ 
} 
+0

\ _ \ _ PRETTY_FUNCTION에 대해 잘 알고 있습니다. \ _ \ _. 굉장히 유용하다! – Maverobot

4

나는 모든 시간을 사용합니다. 내가 걱정하는 유일한 점은 IP를 로그 파일에 남겨 두는 것이다. 함수 이름이 정말 좋다면 영업 비밀을 밝혀 내기가 더 쉬울 수도 있습니다. 그것은 일종의 디버그 기호로, 일을 찾기가 더 어렵습니다. 99.999 %의 케이스에서 나쁜 것은 없습니다.

+0

좋은 지적. 'strings' 유틸리티를 사용하여이 정보를 추출하면 모든 문자열과 유사한 데이터가 실행 파일에서 추출됩니다. 압축 된 실행 파일도 추출 할 수 있습니다. 고객 사이트로 보내는 것을 매우 염두에 두십시오. 종종 경쟁자는 그렇게하지 않아도 실행 파일에 손을 대볼 수 있습니다. – Marty