유용하다고 생각되는 몇 가지 일반적인 함수 속성

4629 단어 blogging

공통 함수 속성





내 이후에는 로봇 공학용 임베디드 C/C++ 프로그래밍 측면에서 더 높은 수준으로 가기 전에 낮은 수준의 관점에서 계속하는 것이 좋을 것이라고 생각합니다.

documentation of gcc 에는 많은 공통 함수 속성이 있습니다. 이 게시물에서는 다음과 같은 몇 가지 함수 속성에 대한 사용 예를 보여 드리겠습니다.
  • __attribute__((warn_unused_result))
  • __attribute__((deprecated))
  • __attribute__((__weak__))

  • 아마도 당신은 아래와 같은 것을 보았을 것입니다.

    #ifndef __must_check
    #define __must_check __attribute__((warn_unused_result))
    #endif
    
    #ifndef __deprecated
    #define __deprecated __attribute__((deprecated))
    #endif
    
    #ifndef __weak
    #define __weak __attribute__((__weak__))
    #endif
    


    __attribute__((warn_unused_result))



    경우에 따라 사용자가 함수의 반환 값을 캡처하도록 하는 것이 매우 중요합니다. 아래와 같이 초기화 과정의 결과를 나타내는 상태 코드가 있습니다.

    int Init() {
      // some status code after certain intiialization process
      return status_code;
    }
    


    이 경우 아래와 같이 함수 호출을 피하고 싶습니다.

    int main(int argc, char **argv) {
      Init();
      return 0;
    }
    


    따라서 함수가 다음과 같도록 __attribute__((warn_unused_result))를 추가할 수 있습니다.

    __attribute__((warn_unused_result)) 
    int Init() {
      // some status code after certain intiialization process
      return status_code;
    }
    


    이 경우 함수의 반환 값이 무시되면(위 예제와 같이 함수 호출) 사용자는 아래와 같은 경고를 받게 됩니다.

    warning: ignoring return value of ‘int Init()’, declared with attribute warn_unused_result [-Wunused-result]
    


    __attribute__((사용되지 않음))



    대부분의 경우 대규모 사용자 그룹이 사용하는 코드베이스를 유지 관리할 때 코드 사용 중단은 매우 정상적이지만 동일한 인터페이스를 유지하기 위해 약속된 기간이 있을 수 있으며 이전 버전과의 호환성도 일반적인 요구 사항입니다. 아래 예제는 호출된 함수가 더 이상 사용되지 않을 때 함수 속성이 사용자에게 경고를 제공하는 데 어떻게 도움이 되는지 보여줍니다.

    __attribute__((deprecated)) int Init();
    


    위의 속성을 가짐으로써 사용자는 Init() 함수를 호출할 때 아래와 같은 경고를 받게 됩니다.

    warning: ‘int Init()’ is deprecated [-Wdeprecated-declarations]
    


    __DEPRECATED_MACRO



    더 이상 사용되지 않음으로 표시하는 것의 연속으로 일부 이전 매크로에 deprecated 로 태그를 지정할 수도 있습니다.

    #define __WARN(msg) __WARN_GCC(GCC warning msg)
    #define __WARN_GCC(s) _Pragma(#s)
    
    #ifndef __DEPRECATED_MACRO
    #define __DEPRECATED_MACRO __WARN("Macro is deprecated")
    #endif
    


    이전에 매크로가 있는 경우

    #define MAX(a,b) (a > b? a: b)
    


    다음과 같이 표시할 수 있습니다.

    #define MAX(a,b) __DEPRECATED_MACRO std::max(a,b)
    


    이제 매크로를 호출하면 출력됩니다.

    warning: Macro is deprecated
    


    __속성__((__약한__))


    gcc 문서에서,

    "weak 속성은 선언이 전역이 아닌 약한 기호로 방출되도록 합니다. 이것은 비함수 선언과 함께 사용할 수도 있지만 주로 사용자 코드에서 재정의할 수 있는 라이브러리 함수를 정의하는 데 유용합니다. 약한 기호는 ELF 대상과 GNU 어셈블러 및 링커를 사용할 때 a.out 대상에 대해 지원됩니다."

    예를 들어

    __attribute__((__weak__)) int Init() { 
      std::cout << "Init is not supported" << std::endl;
      return 0; 
    }
    


    함수를 호출하면 다음과 같은 결과가 출력됩니다.

    Init is not supported
    


    동일한 기능의 정의를 제공하는 다른 번역 단위가 없는 경우.

    정의를 제공하는 다른 파일이 있는 경우

    int Init() { 
        std::cout << "Init done" << std::endl;
        return 2; 
    }
    


    이제 호출 결과Init()는 다음과 같습니다.

    Init done
    


    이 이론은 링커가 약한 기호와 강한 기호를 모두 발견할 때마다 먼저 강한 기호를 선택한다는 것입니다. 약한 기호만 있는 경우 선택됩니다. 이는 정적 라이브러리(.o .a)에만 유효하며 동적(.so) 라이브러리에서는 작동하지 않습니다.
    One Definition Rule를 기준으로 ,

    "개체 및 인라인이 아닌 함수는 전체 프로그램에서 둘 이상의 정의를 가질 수 없습니다."

    따라서 __attribute__((__weak__))를 제거하면 다중 정의에 대해 불평하는 오류가 발생합니다.

    여기까지 포스팅을 마칩니다, 즐겁게 읽어주세요!

    좋은 웹페이지 즐겨찾기