<질문>
int fn();
void whatever()
{
(void) fn();
}
사용하지 않은 반품 가치를 무효화 할 이유가 있습니까, 아니면 완전한 시간 낭비라고 생각하는 것이 맞습니까?
후속 조치 :
꽤 포괄적 인 것 같습니다. 자체 문서화 코드가 주석보다 낫기 때문에 사용하지 않는 반환 값을 주석 처리하는 것보다 낫다고 생각합니다. 개인적으로 불필요한 소음 이니까이 경고를 끄겠습니다.
그것 때문에 벌레가 도망 치면 내 말을 먹어 볼게 ...
<답변1>
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.
<답변2>
직장에서 우리는 함수가 반환 값을 가지고 있음을 인정하기 위해 그것을 사용하지만 개발자는 그것을 무시해도 안전하다고 주장했습니다. 질문에 C ++ 태그를 지정 했으므로 static_cast를 사용해야합니다.
static_cast(fn());
컴파일러가 반환 값을 void로 캐스팅하는 한 의미가 거의 없습니다.
<답변3>
이 작업을 수행하는 진정한 이유는 lint라고하는 C 코드에서 사용되는 도구로 거슬러 올라갑니다.
가능한 문제를 찾고 경고 및 제안을 발행하는 코드를 분석합니다. 함수가 확인되지 않은 값을 반환하면 Lint는 이것이 우연한 경우 경고합니다. 이 경고에서 Lint를 무음으로 처리하려면 호출을 (void)로 캐스팅합니다.
<답변4>
void로 캐스트는 사용되지 않은 변수 및 저장되지 않은 반환 값 또는 표현식에 대한 컴파일러 경고를 억제하는 데 사용됩니다.
Standard (2003)는 §5.2.9 / 4에서 다음과 같이 말합니다.
모든 표현식은 "cv void"유형으로 명시 적으로 변환 할 수 있습니다. 식 값이 삭제됩니다.
따라서 다음과 같이 작성할 수 있습니다.
//suppressing unused variable warnings
static_cast(unusedVar);
static_cast(unusedVar);
static_cast(unusedVar);
//suppressing return value warnings
static_cast(fn());
static_cast(fn());
static_cast(fn());
//suppressing unsaved expressions
static_cast(a + b * 10);
static_cast( x &&y || z);
static_cast( m | n + fn());
모든 양식이 유효합니다. 나는 보통 다음과 같이 짧게 만듭니다.
//suppressing expressions
(void)(unusedVar);
(void)(fn());
(void)(x &&y || z);
그것도 괜찮습니다.
<답변5>
C ++ 17 이후로 void 캐스트 대신 사용할 수있는 [[maybe_unused]] 속성이 있습니다.
<답변6>
Cast to void는 비용이 들지 않습니다. 컴파일러를위한 정보 일뿐입니다.
<답변7>
프로그램의 기능을 위해 void로 캐스팅하는 것은 의미가 없습니다. 또한 David의 답변에서 제안한 것처럼 코드를 읽는 사람에게 신호를 보내는 데 사용해서는 안된다고 주장합니다. 당신의 의도에 대해 뭔가를 전달하고 싶다면 코멘트를 사용하는 것이 좋습니다. 이와 같은 캐스트를 추가하면 이상하게 보이고 가능한 이유에 대한 질문이 제기됩니다. 그냥 내 의견 ...
<답변8>
또한 코드가 MISTA (또는 기타) 표준을 준수하는지 확인할 때 LDRA와 같은 자동 도구는 반환 된 값을 명시 적으로 (void)로 캐스팅하지 않는 한 값을 반환하지 않고 반환 유형이있는 함수를 호출 할 수 없습니다.
<답변9>
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();
f () 호출에서 maybe_unused를 직접 사용할 수 없었습니다.
[[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();
| ^~~~~~~~~~~~~~~~
(무효) 캐스트 작업은 필수는 아니지만 표준에서는 "권장"됩니다. [[nodiscard]] 반환 값을 의도적으로 버릴 수있는 방법은 무엇입니까?
또한 경고 메시지에서 볼 수 있듯이 경고에 대한 한 가지 "해결 방법"은 -Wno-unused-result를 추가하는 것입니다.
g++ -std=c++17 -ggdb3 -O0 -Wall -Wextra -pedantic -Wno-unused-result -o main.out main.cpp
물론 이와 같이 전 세계적으로 경고를 무시하는 것은 권장하지 않습니다.
C ++ 20을 사용하면 https://en.cppreference.com/w/cpp/language/attributes/nodiscard에 언급 된 [[nodiscard ( "reason")]]에서와 같이 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에서 테스트되었습니다.
'개발 > C++' 카테고리의 다른 글
C에서 C ++ 함수를 호출하는 방법은 무엇입니까? (0) | 2020.09.26 |
---|---|
C ++ 함수 템플릿 부분 전문화? (0) | 2020.09.26 |
Qt Creator 프로젝트에 외부 라이브러리 추가 (0) | 2020.09.24 |
C ++ 템플릿 Turing-complete? (0) | 2020.09.24 |