C에서 "사용하지 않은 매개 변수"경고를 표시하지 않는 방법은 무엇입니까?


210

예를 들어 :

Bool NullFunc(const struct timespec *when, const char *who)
{
   return TRUE;
}

C ++ /*...*/에서 매개 변수 에 대한 의견 을 넣을 수있었습니다 . 그러나 물론 C에서는 오류가 발생 error: parameter name omitted합니다.



4
@CiroSantilli이 질문은 더 많은 찬사를 받았으므로 다른 질문을 중복으로 표시하는 것이 좋습니다.
sashoalm


-Wno-unused-parameter, 너무 시끄럽고 버그를 거의 포착하지 않습니다. -Wshadow사용될 때 .
Trass3r

답변:


297

나는 보통 다음과 같은 매크로를 작성합니다.

#define UNUSED(x) (void)(x)

사용하지 않는 모든 매개 변수에이 매크로를 사용할 수 있습니다. (이것은 모든 컴파일러에서 작동합니다.)

예를 들면 다음과 같습니다.

void f(int x) {
    UNUSED(x);
    ...
}

45
방금 (void) x를 사용합니다
Falken Prof. Falken

6
이것이 유일한 휴대용 방법이지만 AFAIK는 나중에 변수를 사용하고 사용하지 않는 줄을 제거하는 것을 잊어 버릴 경우 오해의 소지가 있습니다. 이것이 GCC 미사용 이 좋은 이유 입니다.
ideasman42

6
@ CookSchelling : 아 그러나 당신은 그렇게 사용해서는 안됩니다. 다음과 같이하십시오 : void f(int x) {UNUSED(x);}.
Job

9
@Alcott (내 경우와 마찬가지로) 함수는 함수 포인터로 참조되기 때문에 동일한 서명을 가져야하는 많은 것 중 하나 일 수 있기 때문입니다.
josch

17
이것을 사용하여 #define UNUSED(...) (void)(__VA_ARGS__)여러 변수에 적용 할 수 있습니다.
Matthew Mitchell

110

gcc에서는 unused속성으로 매개 변수에 레이블을 지정할 수 있습니다 .

변수에 첨부 된이 속성은 변수를 사용하지 않을 수 있음을 의미합니다 . GCC는이 변수에 대해 경고를 생성하지 않습니다.

실제로 이것은 __attribute__ ((unused))매개 변수 바로 앞에 두어 수행됩니다 . 예를 들면 다음과 같습니다.

void foo(workerid_t workerId) { }

된다

void foo(__attribute__((unused)) workerid_t workerId) { }

24
나와 같은 초보자에게는 __attribute__ ((unused))논쟁의 앞에 놓는 것을 의미 합니다.
josch

2
@ josch 나는 당신이 완전히 정확하다고 생각하지만 문서 는 매개 변수 뒤에 넣어야한다고 암시하는 것 같습니다 . 두 옵션 모두 문제없이 지원 될 수 있습니다.
안토니오

또한주의 __attribute__((unused))이다 독점적 인 GCC 확장 . 다른 컴파일러에서 지원하지만 MSVC에서는 작동하지 않는다고 가정합니다. 이것은 컴파일러 표준의 일부가 아니므로 다른 옵션만큼 이식성이
Zoe

58

gcc / clang의 사용하지 않는 속성을 사용할 수 있지만 헤더에 이러한 매크로를 사용하여 소스 전체에 gcc 관련 속성을 사용하지 않으며 모든 __attribute__곳에서 약간의 장황한 / 추악한 사용을 피할 수 있습니다.

#ifdef __GNUC__
#  define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
#else
#  define UNUSED(x) UNUSED_ ## x
#endif

#ifdef __GNUC__
#  define UNUSED_FUNCTION(x) __attribute__((__unused__)) UNUSED_ ## x
#else
#  define UNUSED_FUNCTION(x) UNUSED_ ## x
#endif

그럼 당신은 할 수 ...

void foo(int UNUSED(bar)) { ... }

bar코드 어디에서나 사용하려고하면 오류가 발생 하여 실수로 속성을 남길 수 없기 때문에 이것을 선호합니다 .

그리고 기능을 위해 ...

static void UNUSED_FUNCTION(foo)(int bar) { ... }

참고 1) :
내가 아는 한 MSVC는에 해당하지 않습니다 __attribute__((__unused__)).

주 2) : 매크로, 괄호를 포함하는 인수하지 작동 이 같은 인수가 있다면 그래서 당신이 할 수 할, 또는 받는 사람, 이것은 유일한 단점입니다 매크로 내가 지금까지 발견이 경우에 나는 후퇴 에
UNUSED
float (*coords)[3]
float UNUSED((*coords)[3])float (*UNUSED(coords))[3]UNUSED(void)coords;


아니면 #define __attribute__(x)비 GCC 환경 (AFAIK __attribute__는 MSVC에서 지원 하지 않습니다 )입니까?
Franklin Yu

그것은 작동 할 수 있지만 Dunder 접두어는 컴파일러를 위해 예약되어 있으므로 이것을 피할 것입니다.
ideasman42

내 gcc의 경우 최소한 식별자 앞에 속성 지정자를 넣는 것이 func, vars 및 parameter에 올바르게 작동하는 것처럼 보이므로 #define POSSIBLY_UNUSED (identifier) attribute __ ((__ unused )) identifier와 같은 것을 세 가지 모두에 사용할 수 있습니다
Britton Kerin

퍼팅 할 때 내가 얻을 후 warning: unused parameter ‘foo’ [-Wunused-parameter](GCC 7.3.0)
ideasman42

19

사용하지 않는 속성을 가진 gcc를 사용하는 경우 :

int foo (__attribute__((unused)) int bar) {
    return 0;
}

16

이것이 gcc로 표시되어 있으면 명령 행 스위치를 사용할 수 있습니다 Wno-unused-parameter.

예를 들면 다음과 같습니다.

gcc -Wno-unused-parameter test.c

물론 이것은 전체 파일에 영향을 미치며 스위치를 설정 한 위치에 따라 프로젝트에 영향을 주지만 코드를 변경할 필요는 없습니다.


7

소스 코드 블록에 대해 사용되지 않은 매개 변수 경고를 억제하는 gcc / g ++ 고유의 방법은 다음 pragma 명령문으로이를 묶는 것입니다.

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
<code with unused parameters here>
#pragma GCC diagnostic pop

Clang은 이러한 진단 pragma도 지원합니다 clang.llvm.org/docs/…
eush77

4

속성에 레이블을 지정하는 것이 이상적입니다. 매크로는 언젠가 혼란을 초래합니다. void (x)를 사용하여 처리 중에 오버 헤드를 추가하고 있습니다.

입력 인수를 사용하지 않는 경우

void foo(int __attribute__((unused))key)
{
}

함수 내에 정의 된 변수를 사용하지 않는 경우

void foo(int key)
{
   int hash = 0;
   int bkt __attribute__((unused)) = 0;

   api_call(x, hash, bkt);
}

이제 나중에 논리에 해시 변수를 사용하지만 bkt는 필요하지 않습니다. bkt를 사용하지 않는 것으로 정의하십시오. 그렇지 않으면 컴파일러에서 "bkt set bt not used"라고 말합니다.

참고 : 이것은 최적화가 아닌 경고를 억제하기위한 것입니다.


1
를 사용하여 처리시 오버 헤드를 추가하지 않으면 void(x)컴파일러가이를 최적화합니다.
Majora320

4

나는 같은 문제를 겪었다. 제 3 자 라이브러리를 사용했습니다. 이 라이브러리를 컴파일하면 컴파일러 (gcc / clang)는 사용되지 않는 변수에 대해 불평합니다.

이렇게

test.cpp : 29 : 11 : 경고 : 변수 '매직'이 설정되었지만 사용되지는 않음 [-미사용-하지만 변수가 설정 됨] 짧은 마법 [] = {

test.cpp : 84 : 17 : 경고 : 사용하지 않는 변수 'before_write'[-Wunused-variable] int64_t before_write = Thread :: currentTimeMillis ();

따라서 해결책은 매우 분명합니다. -Wno-unusedgcc / clang CFLAG로 추가하면 "사용하지 않은"모든 경고가 표시되지 않습니다 -Wall.

이런 식으로 코드를 변경할 필요가 없습니다.


1
사용하지 않는 모든 경고를 실제로 무시하려는 경우에는 문제가되지 않지만 거의 그렇지 않습니다. 일반적으로 무시하려는 특정 인스턴스입니다.
Dan Bechard

1

MSVC에서 특정 경고를 표시하지 않으려면 컴파일러의 번호를 / wd #로 지정하면 충분합니다. 내 CMakeLists.txt에는 다음과 같은 블록이 포함되어 있습니다.

If (MSVC)
    Set (CMAKE_EXE_LINKER_FLAGS "$ {CMAKE_EXE_LINKER_FLAGS} / NODEFAULTLIB: LIBCMT")
    Add_definitions (/W4 /wd4512 /wd4702 /wd4100 /wd4510 /wd4355 /wd4127)
    Add_definitions (/D_CRT_SECURE_NO_WARNINGS)
Elseif (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_GNUC)
    Add_definitions (-Wall -W -pedantic)
Else ()
    Message ("Unknown compiler")
Endif ()

이제 3 년 동안 MSVC에주의를 기울이지 않기 때문에 / wd4512 / wd4702 / wd4100 / wd4510 / wd4355 / wd4127이 정확히 무엇을 의미하는지 말할 수는 없지만 결과에 영향을 미치지 않는 과도한 경고를 억제합니다.


0

이 스타일이 사용되는 것을 보았습니다.

if (when || who || format || data || len);

14
흠. 나는 이것이 관련된 모든 매개 변수가 부울로 변환 될 수 있다고 가정하기 때문에 이것을 좋아한다고 말할 수는 없습니다.
Suma

1
비록 컴파일러가 거의 확실하게 최적화 할 것이지만, 진행 상황을 명확하게 알지 못하고 정적 소스 체커를 혼동시킬 수는 있지만 이것은 실제로 좋은 규칙은 아닙니다. 여기 다른 제안 중 하나를 더 잘 사용하십시오.
ideasman42

1
아직 답장을 받고 있다고 믿을 수 없습니다. 질문은 그것이 C에 대한 것이라고 진술했습니다. 그렇습니다. 다른 언어로는 작동하지 않습니다.
Iustin

2
나는 참신 요소로 +1을 사용하지 않을 것입니다.
mgalgs 2012 년

2
변수의 진실 을 확인 하면 구조체에 경고를 줄 수 있습니다. 예. struct { int a; } b = {1}; if (b);GCC는 경고합니다 used struct type value where scalar is required.
ideasman42

-1

레코드의 경우 위의 Job 답변을 좋아하지만 "do-nothing"문에서 변수 이름 만 사용하는 솔루션이 궁금합니다.

void foo(int x) {
    x; /* unused */
    ...
}

물론 이것은 단점이있다. 예를 들어 "사용하지 않은"메모가 없으면 의도적 인 코드 줄이 아니라 실수처럼 보입니다.

장점은 정의가 필요하지 않으며 경고를 제거한다는 것입니다.

성능, 최적화 또는 기타 차이점이 있습니까?


2
나는 이것을 MSVC와 함께 사용했지만 GCC는 "효과없이 진술"경고를 발생시킵니다. 따라서 Job의 솔루션은 갈 길입니다.
Dmitrii Semikin

이 접근법은 여전히 ​​XCode에서 경고를 생성합니다
MOK9
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.