programing

반환값이 무시될 경우 경고는 어떻게 발생합니까?

javaba 2022. 8. 13. 16:55
반응형

반환값이 무시될 경우 경고는 어떻게 발생합니까?

코드(C++)에서 함수의 반환값을 무시한 모든 위치를 보고 싶습니다.gcc 또는 정적 코드 분석 도구를 사용하여 어떻게 해야 합니까?

잘못된 코드 예:

int f(int z) {
    return z + (z*2) + z/3 + z*z + 23;
}


int main()
{
  int i = 7;
  f(i); ///// <<----- here I disregard the return value

  return 1;
}

주의해 주십시오.

  • 함수와 그 용도가 다른 파일에 있어도 동작합니다.
  • 프리 스태틱 체크 도구

GCC를 원하십니까?warn_unused_result속성:

#define WARN_UNUSED __attribute__((warn_unused_result))

int WARN_UNUSED f(int z) {
    return z + (z*2) + z/3 + z*z + 23;
}

int main()
{
  int i = 7;
  f(i); ///// <<----- here i disregard the return value
  return 1;
}

이 코드를 컴파일하면 다음과 같은 결과가 발생합니다.

$ gcc test.c
test.c: In function `main':
test.c:16: warning: ignoring return value of `f', declared with
attribute warn_unused_result

Linux 커널에서 사용 중인 것을 알 수 있습니다.이것들은__must_check이 기능을 사용하려면 GCC 3.4 이상이 필요한 것 같습니다.그러면 커널 헤더 파일에서 사용되는 매크로를 찾을 수 있습니다.

unsigned long __must_check copy_to_user(void __user *to,
                                        const void *from, unsigned long n);

C++17의 경우 [nodiscard]속성이 있기 때문에 이 질문에 대한 답변이 변경됩니다.[dcl.attr.nodiscard]에 기재되어 있습니다.

attribute-token nodiscard는 함수 선언의 선언자 ID 또는 클래스 선언 또는 열거에 적용할 수 있습니다.각 속성 목록에 한 번만 표시되어야 하며 속성 인수 절제는 없어야 합니다.

그리고.

[예:

struct [[nodiscard]] error_info { /* ... */ };
error_info enable_missile_safety_mode();
void launch_missiles();
void test_missiles() {
  enable_missile_safety_mode(); // warning encouraged
  launch_missiles();
}
error_info &foo();
void f() { foo(); }             // warning not encouraged: not a nodiscard call, because neither
                                // the (reference) return type nor the function is declared nodiscard

: end 예시]

따라서 예를 수정합니다(실시간 참조).

[[nodiscard]] int f(int z) {
    return z + (z*2) + z/3 + z*z + 23;
}


int main()
{
  int i = 7;
  f(i); // now we obtain a diagnostic

  return 1;
}

이제 gcc와 clang을 모두 사용하여 진단을 받습니다.

warning: ignoring return value of function declared with 'nodiscard' attribute [-Wunused-result]
  f(i); // now we obtain a diagnostic
  ^ ~

제가 알기로는 이 경고를 줄 수 있는 GCC 옵션은 없습니다.다만, 특정의 기능에 관심이 있는 경우는, 다음의 어트리뷰트로 태그 붙일 수 있습니다.

int fn() __attribute__((warn_unused_result));

반환값 fn()이 사용되지 않은 경우 경고가 표시됩니다.경고:저는 이 기능을 사용해 본 적이 없습니다.

이 편리한 템플릿을 사용하여 런타임에 수행할 수 있습니다.

에러 코드(HRESULT 등)를 반환하는 대신 return_code<를 반환한다.HRESULT >: 값을 읽지 않고 범위를 벗어날 경우 단언합니다.정적 분석 도구는 아니지만 여전히 유용합니다.

class return_value
{
public:
  explicit return_value(T value)
    :value(value), checked(false)
  {
  }

  return_value(const return_value& other)
    :value(other.value), checked(other.checked)
  {
    other.checked = true;
  }

  return_value& operator=(const return_value& other)
  {
    if( this != &other ) 
    {
      assert(checked);
      value = other.value;
      checked = other.checked;
      other.checked = true;
    }
  }

  ~return_value(const return_value& other)
  {
    assert(checked);
  }

  T get_value()const {
    checked = true;
    return value;
  }

private:
  mutable bool checked;
  T value;
};

모든 정적 분석 코드(PC-Lint 등)를 통해 알 수 있습니다.PC-Lint의 경우, 이것이 사실이라는 것을 알고 있습니다.

정적 분석기가 대신 작동하지만 코드 베이스가 더 사소한 경우 압도당할 준비를 합니다;-)

여기서는 정적 분석기를 사용하는 것이 가장 좋습니다.여기서는 Coverity를 사용하지만 사용할 수 있는 무료 툴도 있습니다.

Linux 스타일의 셸을 사용하고 있는 경우, 재빠르고 더러운 솔루션이 필요한 경우, 다음과 같은 방법을 시도해 볼 수 있습니다.

grep -rn "function_name" * | grep -v "="

지정된 함수를 참조하지만 "="가 포함되지 않은 모든 행을 찾습니다.많은 false positive(및 일부 false negative)를 얻을 수 있지만, 정적 분석기가 없는 경우 이 방법을 사용하는 것이 좋습니다.

고전적인 'lint' 프로그램은 무시된 값을 반환하는 함수에 대해 매우 수다스러웠습니다.문제는, 이러한 경고의 대부분이 불필요한 것이어서, 보풀의 출력에 과도한 노이즈가 발생했다는 것입니다(무시하고 싶은 것은 솜털을 집어내는 것이었습니다).그래서 GCC에 표준 경고가 없는 것 같습니다.

또 다른 문제인 반대 측면은 "결과를 무시하고 있지만 실제로는 상관하지 않을 때 경고를 어떻게 억제하느냐"입니다.이를 위한 전형적인 시나리오는 다음과 같습니다.

if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
    signal(SIGHUP, sighandler);

은 첫 에 드는데요.signal(); SIG_IGN의 SIG_IGN의 SIG_SIG_IGN은 SIG_IGN을 사용합니다.경고에서 벗어나기 위해 다음과 같은 변종을 사용할 수 있습니다.

if ((old = signal(SIGHUP, SIG_IGN)) != SIG_IGN)
    old = signal(SIGHUP, sighandler);

하면 '아까', '아까', '아까'에 할당이 됩니다.old 하다.== 붙이면 .★★★★★★★★★★★★★==SIG_IGN)을 사용합니다.

언급URL : https://stackoverflow.com/questions/2042780/how-to-raise-warning-if-return-value-is-disregarded

반응형