답변:
David의 대답 은이 함수가 반환하는 것을 알고 있지만 명시 적으로 무시하고 있음을 다른 "개발자"에게 명시 적으로 보여 주려는 동기를 거의 다룹니다.
이는 필요한 오류 코드가 항상 처리되도록하는 방법입니다.
C ++의 경우 전체 정적 캐스트 표기법을 사용하는 것이 과도하게 느껴지기 때문에 C 스타일 캐스트도 사용하는 것을 선호하는 유일한 장소라고 생각합니다. 마지막으로 코딩 표준을 검토하거나 작성하는 경우 오버로드 된 연산자 (함수 호출 표기를 사용하지 않음)에 대한 호출도 이것에서 제외되어야한다고 명시 적으로 명시하는 것도 좋습니다.
class A {};
A operator+(A const &, A const &);
int main () {
A a;
a + a; // Not a problem
(void)operator+(a,a); // Using function call notation - so add the cast.
직장에서 우리는 함수가 반환 값을 가지고 있음을 인정하기 위해 그것을 사용하지만 개발자는 그것을 무시해도 안전하다고 주장했습니다. 질문에 C ++ 태그를 지정 했으므로 static_cast 를 사용해야합니다 .
static_cast<void>(fn());
컴파일러가 반환 값을 void로 캐스팅하는 한 의미가 거의 없습니다.
이 작업을 수행하는 진정한 이유는 lint 라는 C 코드에서 사용 된 도구로 거슬러 올라갑니다 .
가능한 문제를 찾고 경고 및 제안을 발행하는 코드를 분석합니다. 함수가 확인되지 않은 값을 반환하면 lint
우연한 경우 경고합니다. lint
이 경고 를 무음 으로 처리 하려면으로 전화를 (void)
겁니다.
캐스팅 대상 void
은 사용되지 않은 변수 및 저장되지 않은 반환 값 또는 식에 대한 컴파일러 경고를 억제하는 데 사용됩니다.
Standard (2003)는 §5.2.9 / 4에서 다음과 같이 말합니다.
모든 표현식은 "cv void"유형으로 명시 적으로 변환 할 수 있습니다. 식 값이 삭제됩니다 .
따라서 다음과 같이 작성할 수 있습니다.
//suppressing unused variable warnings
static_cast<void>(unusedVar);
static_cast<const void>(unusedVar);
static_cast<volatile void>(unusedVar);
//suppressing return value warnings
static_cast<void>(fn());
static_cast<const void>(fn());
static_cast<volatile void>(fn());
//suppressing unsaved expressions
static_cast<void>(a + b * 10);
static_cast<const void>( x &&y || z);
static_cast<volatile void>( m | n + fn());
모든 양식이 유효합니다. 나는 보통 다음과 같이 짧게 만듭니다.
//suppressing expressions
(void)(unusedVar);
(void)(fn());
(void)(x &&y || z);
그것도 괜찮습니다.
C ++ 17 이후로 캐스트 [[maybe_unused]]
대신 사용할 수있는 속성이 있습니다 void
.
nodiscard
. stackoverflow.com/a/61675726/895245 또한 [[maybe_unused]]
호출에 직접 적용 할 수 없다고 생각합니다 . 호출의 반환을 받아들이는 더미 변수에만 적용 할 수 있습니까? 그것이 맞다면 약간 불안정합니다.
프로그램의 기능을 위해 void로 캐스팅하는 것은 의미가 없습니다. 또한 David의 답변에서 제안한 것처럼 코드를 읽는 사람에게 신호를 보내는 데 사용해서는 안된다고 주장합니다. 당신의 의도에 대해 뭔가를 전달하고 싶다면 코멘트를 사용하는 것이 좋습니다. 이와 같은 캐스트를 추가하면 이상하게 보이고 가능한 이유에 대한 질문이 제기됩니다. 그냥 내 의견 ...
For the functionality of you program casting to void is meaningless
자기 설명서 및 컴파일 경고 수, 그것은 정말 아니다. 코드가 스스로 설명 할 때 you should not use it to signal something to the person that is reading the code [...] it is better to use a comment.
가장 좋은 주석은 주석 없음 입니다. 그리고 다시 말하지만, 유효한 경고 컴파일러가 프로세스에서 행복하게 유지됩니다.
C ++ 17 [[nodiscard]]
C ++ 17은 속성으로 "반환 값 무시 비즈니스"를 표준화했습니다.
따라서 준수 구현이 항상 nodiscard
주어진 경우에만 경고하고 그렇지 않으면 경고하지 않기를 바랍니다 .
예:
main.cpp
[[nodiscard]] int f() {
return 1;
}
int main() {
f();
}
엮다:
g++ -std=c++17 -ggdb3 -O0 -Wall -Wextra -pedantic -o main.out main.cpp
결과:
main.cpp: In function ‘int main()’:
main.cpp:6:6: warning: ignoring return value of ‘int f()’, declared with attribute nodiscard [-Wunused-result]
6 | f();
| ~^~
main.cpp:1:19: note: declared here
1 | [[nodiscard]] int f() {
|
다음은 모두 경고를 피합니다.
(void)f();
[[maybe_unused]] int i = f();
통화에서 maybe_unused
직접 사용할 수 없었습니다 f()
.
[[maybe_unused]] f();
제공합니다 :
main.cpp: In function ‘int main()’:
main.cpp:6:5: warning: attributes at the beginning of statement are ignored [-Wattributes]
6 | [[maybe_unused]] f();
| ^~~~~~~~~~~~~~~~
(void)
캐스트 작업 표준에 의무적으로 표시되지 않지만 "격려"입니다 : 내가 의도적으로 [[nodiscard] 반환 값을 폐기 할 수 있습니까?
또한 경고 메시지에서 볼 수 있듯이 경고에 대한 한 가지 "해결 방법"은 다음을 추가하는 것입니다 -Wno-unused-result
.
g++ -std=c++17 -ggdb3 -O0 -Wall -Wextra -pedantic -Wno-unused-result -o main.out main.cpp
물론 이와 같이 전 세계적으로 경고를 무시하는 것은 권장하지 않습니다.
C ++ 20은 또한 당신이 이유를 추가 할 수 있습니다 nodiscard
같이 [[nodiscard("reason")]]
:에서 언급 한 바와 같이 https://en.cppreference.com/w/cpp/language/attributes/nodiscard
GCC warn_unused_result
속성
의 표준화 [[nodiscard]]
이전과 C가 속성을 표준화하기로 결정하기 전에 GCC는 다음과 같은 기능을 구현했습니다 warn_unused_result
.
int f() __attribute__ ((warn_unused_result));
int f() {
return 1;
}
int main() {
f();
}
다음을 제공합니다.
main.cpp: In function ‘int main()’:
main.cpp:8:6: warning: ignoring return value of ‘int f()’, declared with attribute warn_unused_result [-Wunused-result]
8 | f();
| ~^~
ANSI C는이에 대한 표준이 없기 때문에, ANSI C는 C 표준 라이브러리 함수는 속성이 없거나 따라서 구현 또는 표시되지해야하는지에 자신의 결정을 한 지정하지 않는 다음에 유의해야한다 warn_unuesd_result
,하는 일반적 (void)
으로 모든 구현에서 경고를 완전히 피하기 위해 표준 라이브러리 함수에 대한 호출의 반환을 무시 하기 위해 캐스트 를 사용해야하는 이유입니다 .
GCC 9.2.1, Ubuntu 19.10에서 테스트되었습니다.