`nodiscard` 속성 — 반환값을 버리지 마세요
nodiscard 속성 — 반환값을 버리지 마세요
함수의 반환값을 신경 쓰지 않는 코드가 오늘도 많이 보이죠. malloc이 실패했는데도 반환값을 무시해 버리면, 정작 메모리가 부족한 상황에서 조용히 넘어가 버려요. C23에서 도입된 [[nodiscard]] 속성은 이런 실수를 컴파일러가 짚어주도록 만드는 장치예요. 함수나 타입에 붙여 두면, 반환값을 쓰지 않고 버리는 코드에서 경고를 내주거든요.
출처: cppreference
본문
문법(Syntax)
[[nodiscard]] (1)
[[__nodiscard__]] (1)
[[nodiscard( string-literal )]] (2)
[[__nodiscard__( string-literal )]] (2)
string-literal은 결과를 버리면 안 되는 이유를 설명하는 텍스트로, 보통 경고 메시지에 함께 실려요.
설명(Explanation)
함수 선언, 열거형 선언, 또는 구조체/공용체 선언에 나타날 수 있어요.
void로의 캐스트가 아닌, 값을 버리는 표현식(discarded-value expression)에서 다음 중 하나라도 일어나면 컴파일러는 경고를 내도록 권장돼요.
nodiscard로 선언된 함수를 호출했거나,nodiscard로 선언된 구조체/공용체/열거형을 반환하는 함수를 호출했을 때요.
string-literal을 지정했다면, 보통 그 문자열이 경고에 포함돼요.
값을 버리지 않고 변수에 담으면 경고가 나지 않는다는 점이 핵심이에요.
예제(Example)
struct [[nodiscard]] error_info { int status; /*...*/ };
struct error_info enable_missile_safety_mode() { /*...*/ return (struct error_info){0}; }
void launch_missiles() { /*...*/ }
void test_missiles() {
enable_missile_safety_mode(); // compiler may warn on discarding a nodiscard value
launch_missiles();
}
struct error_info* foo() { static struct error_info e; /*...*/ return &e; }
void f1() {
foo(); // nodiscard type itself is not returned, no warning
}
// nodiscard( string-literal ):
[[nodiscard("PURE FUN")]] int strategic_value(int x, int y) { return x ^ y; }
int main()
{
strategic_value(4,2); // compiler may warn on discarding a nodiscard value
int z = strategic_value(0,0); // OK: return value is not discarded
return z;
}
가능한 출력(예시):
game.cpp:5:4: warning: ignoring return value of function declared with 'nodiscard' attribute
game.cpp:17:5: warning: ignoring return value of function declared with 'nodiscard' attribute: PURE FUN
foo()가 nodiscard 타입인 struct error_info의 포인터를 반환할 때는 경고가 없어요. 속성이 붙은 건 반환 타입 자체이지 포인터가 아니기 때문이에요.
더 알아보기
[[noreturn]],[[unsequenced]]같은 다른 속성 문서와 함께 보면 C23 속성의 쓰임새 전체가 그려져요.