C ++ => 컴파일러 버그 또는 코드 버그에서 사용하지 않은 변수 경고를 억제 하시겠습니까?
-
19-09-2019 - |
문제
현재, 나는 사용하지 않는 가변 경고를 억제하기 위해 다음 함수 템플릿을 사용하고 있습니다.
template<typename T>
void
unused(T const &) {
/* Do nothing. */
}
그러나 Linux에서 Cygwin으로 포팅 할 때 G ++ 3.4.4에서 컴파일러 오류가 발생하고 있습니다 (Linux에서는 3.4.6이므로 버그 수정일까요?) :
Write.cpp: In member function `void* Write::initReadWrite()':
Write.cpp:516: error: invalid initialization of reference of type 'const volatile bool&' from expression of type 'volatile bool'
../../src/common/Assert.h:27: error: in passing argument 1 of `void unused(const T&) [with T = volatile bool]'
make[1]: *** [ARCH.cygwin/release/Write.o] Error 1
미사용에 대한 주장은 다음과 같이 선언 된 회원 변수입니다.
volatile bool readWriteActivated;
내 코드의 컴파일러 버그입니까 아니면 버그입니까?
최소 테스트 사례는 다음과 같습니다.
template<typename T>
void unused(T const &) { }
int main() {
volatile bool x = false;
unused(!x); // type of "!x" is bool
}
해결책 3
다른 팁
실제로 매개 변수를 사용하지 않음을 나타내는 실제 방법은 이름을 제공하지 않습니다.
int f(int a, float) {
return a*2;
}
사용하지 않은 부유물에 대한 경고없이 모든 경고가 켜져있는 상태에서 모든 곳을 컴파일합니다. 인수가 프로토 타입에 이름이있는 경우에도 int f(int a, float f);
), 여전히 불평하지 않습니다.
나는 이것이 휴대가 가능하다는 것을 100% 확신하지는 않지만, 이것은 사용하지 않은 변수에 대한 경고를 억제하는 데 일반적으로 사용한 관용구입니다. 여기서 컨텍스트는 잡기 위해서만 사용되는 신호 처리기입니다. SIGINT
그리고 SIGTERM
, 함수가 호출되면 프로그램이 종료 될 때입니다.
volatile bool app_killed = false;
int signal_handler(int signum)
{
(void)signum; // this suppresses the warnings
app_killed = true;
}
나는 매개 변수 목록을 혼란스럽게하는 것을 싫어하는 경향이있다. __attribute__((unused))
, 캐스트-투효 트릭은 Visual C ++를 위해 매크로에 의지하지 않고 작동하기 때문에 작동합니다.
GCC에서는 매크로를 다음과 같이 정의 할 수 있습니다.
#ifdef UNUSED
#elif defined(__GNUC__)
# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
#elif defined(__LCLINT__)
# define UNUSED(x) /*@unused@*/ x
#else
# define UNUSED(x) x
#endif
이 매크로로 표시된 모든 매개 변수는 사용되지 않은 경고 GCC 방출을 억제합니다 (그리고 접두사로 매개 변수를 이름 바꾸십시오. UNUSED_
). Visual Studio의 경우 경고를 억제 할 수 있습니다. #pragma
지령.
Haavee가 제안한 답변 (UR에 의해 수정)은 내가 일반적으로 사용하는 것입니다.
int f(int a, float /*epsilon*/) {
return a*2;
}
실제 문제는 논쟁이있을 때 발생합니다 때때로 그러나이 방법에 항상 사용되는 것은 아닙니다.
int f(int a, float epsilon) {
#ifdef LOGGING_ENABLED
LOG("f: a = %d, epsilon = %f\n", a, epsilon);
#endif
return a*2;
}
이제 매개 변수 이름 Epsilon에 댓글을 달 수 없습니다. 로깅 빌드를 중단하기 때문입니다 (인수 목록에 다른 #ifdef를 삽입하고 싶지는 않습니다. 코드를 읽기가 훨씬 어려워지기 때문입니다).
그래서 최선의 해결책은 Tom의 제안을 사용하는 것입니다.
int f(int a, float epsilon) {
(void) epsilon; // suppress compiler warning for possibly unused arg
#ifdef LOGGING_ENABLED
LOG("f: a = %d, epsilon = %f\n", a, epsilon);
#endif
return a*2;
}
내 유일한 걱정은 일부 컴파일러가 "(void) Epsilon;"에 대해 경고 할 수 있다는 것입니다. 진술, 예를 들어 "진술은"경고 나 그와 같은 효과가 없습니다.