Como suprimir avisos de "parâmetro não utilizado" em C?

210

Por exemplo:

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

Em C ++, pude colocar um /*...*/comentário em torno dos parâmetros. Mas não em C, é claro, onde isso me dá o erro error: parameter name omitted.

nixgadget
fonte
possível duplicata Qual é a melhor maneira para suprimir "não utilizado variável x" -warning
Ciro Santilli郝海东冠状病六四事件法轮功
4
@CiroSantilli Esta questão tem mais votos positivos, seria melhor marcar a outra pergunta como duplicada.
sashoalm
1
Veja também a versão em C ++ desta pergunta
Shafik Yaghmour
-Wno-unused-parameter, é muito barulhento e raramente pega bugs esp. quando -Wshadowé usado.
Trass3r

Respostas:

297

Eu costumo escrever uma macro como esta:

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

Você pode usar essa macro para todos os seus parâmetros não utilizados. (Observe que isso funciona em qualquer compilador.)

Por exemplo:

void f(int x) {
    UNUSED(x);
    ...
}
Trabalho
fonte
45
Eu só uso (void) x diretamente
Prof. Falken
6
Embora essa seja a única maneira portátil do AFAIK, o aborrecimento disso é que pode ser enganoso se você usar a variável posteriormente e esquecer de remover a linha não utilizada. é por isso que o GCC não utilizado é bom.
usar o seguinte código
6
@CookSchelling: Ah, mas você não deve usá-lo assim. Fazer algo parecido com isto: void f(int x) {UNUSED(x);}.
Job
9
@ Alcott porque (como no meu caso) a função pode ser uma das muitas que precisam ter a mesma assinatura porque são referenciadas por um ponteiro de função.
Josch
17
Estou usando o #define UNUSED(...) (void)(__VA_ARGS__)que me permite aplicar isso a várias variáveis.
Matthew Mitchell
110

Em gcc, você pode rotular o parâmetro com o unusedatributo .

Esse atributo, anexado a uma variável, significa que a variável deve ser possivelmente não utilizada. O GCC não produzirá um aviso para essa variável.

Na prática, isso é realizado colocando um __attribute__ ((unused))pouco antes do parâmetro. Por exemplo:

void foo(workerid_t workerId) { }

torna-se

void foo(__attribute__((unused)) workerid_t workerId) { }
fluxo
fonte
24
Para qualquer iniciante como eu, isso significa colocar __attribute__ ((unused))na frente do argumento.
Josch
2
@josch Eu acho que você está totalmente correto, mas a documentação parece sugerir que ela deve ser colocada após o parâmetro. As duas opções provavelmente são suportadas sem problemas.
Antonio
Observe também que __attribute__((unused))é uma extensão proprietária do GCC . É suportado por outros compiladores, mas presumo que isso não funcione com o MSVC. Porém, não faz parte diretamente do padrão do compilador, portanto, não é tão portátil quanto algumas outras opções
Zoe
58

Você pode usar o atributo não utilizado do gcc / clang, no entanto, eu uso essas macros em um cabeçalho para evitar atributos específicos do gcc em toda a fonte, além de ter em __attribute__todos os lugares um pouco detalhado / feio.

#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

Então você pode fazer ...

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

Prefiro isso porque você recebe um erro se tentar usar baro código em qualquer lugar, para não deixar o atributo por engano.

e para funções ...

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

Nota 1):
Até onde eu sei, o MSVC não tem um equivalente a __attribute__((__unused__)).

Nota 2):
a UNUSEDmacro não funcionará para argumentos que contenham parênteses;
portanto , se você tiver um argumento como float (*coords)[3] não pode ,
float UNUSED((*coords)[3])ou float (*UNUSED(coords))[3], essa é a única desvantagem doUNUSED macro que encontrei até agora, nesses casos, recuo para(void)coords;

ideasman42
fonte
Ou talvez apenas #define __attribute__(x)para ambientes não pertencentes ao GCC (nenhum dos AFAIK __attribute__é suportado pelo MSVC)?
Franklin Yu
Isso pode funcionar, mas termos prefixados dunder são reservados para o compilador, então prefiro evitar isso.
ideasman42
Para o meu gcc, pelo menos colocar o especificador de atributo antes que o identificador funcione corretamente para funcs, vars e parâmetro, então algo como #define POSSIBLY_UNUSED (identifier) attribute __ ((__ unused )) identifier pode ser usado para todos os três
Britton Kerin
Ao colocá-lo depois de eu ter warning: unused parameter ‘foo’ [-Wunused-parameter](gcc 7.3.0)
ideasman42
19

Com o gcc com o atributo não utilizado:

int foo (__attribute__((unused)) int bar) {
    return 0;
}
Urso de pelúcia
fonte
16

Vendo que isso está marcado como gcc, você pode usar a opção de linha de comando Wno-unused-parameter.

Por exemplo:

gcc -Wno-unused-parameter test.c

É claro que isso afeta o arquivo inteiro (e talvez o projeto dependa de onde você configurou a opção), mas você não precisa alterar nenhum código.

Paul Hutchinson
fonte
7

Uma maneira específica de gcc / g ++ de suprimir o aviso de parâmetro não utilizado para um bloco de código-fonte é anexá-lo às seguintes instruções pragma:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
<code with unused parameters here>
#pragma GCC diagnostic pop
calma
fonte
Clang suporta esses pragmas de diagnóstico, bem clang.llvm.org/docs/...
eush77
4

Rotular o atributo é a maneira ideal. O MACRO gera confusão em algum momento. e usando void (x), estamos adicionando uma sobrecarga no processamento.

Se não estiver usando o argumento de entrada, use

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

Se não estiver usando a variável definida dentro da função

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

   api_call(x, hash, bkt);
}

Agora, mais tarde, usando a variável hash para sua lógica, mas não precisa de bkt. defina bkt como não utilizado, caso contrário, o compilador diz 'bkt set bt não usado ".

NOTA: Isso é apenas para suprimir o aviso, não para otimização.

user2452561
fonte
1
Você não adiciona nenhuma sobrecarga no processamento usando void(x), o compilador a otimizará.
Majora320
4

Eu tenho o mesmo problema. Eu usei uma biblioteca de terceiros. Quando eu compilar esta biblioteca, o compilador (gcc / clang) reclamará sobre variáveis ​​não utilizadas.

Como isso

test.cpp: 29: 11: aviso: variável 'mágica' definida, mas não usada [-Wunused-but-set-variable] short magic [] = {

test.cpp: 84: 17: aviso: variável não utilizada 'before_write' [-Wunused-variable] int64_t before_write = Thread :: currentTimeMillis ();

Portanto, a solução é bastante clara. Adicionar -Wno-unusedCFLAG como gcc / clang suprimirá todos os avisos "não utilizados", mesmo que você tenha -Walldefinido.

Dessa forma, você NÃO PRECISA alterar nenhum código.

landerlyoung
fonte
1
Isso é bom se você realmente deseja ignorar todos os avisos não utilizados, mas quase nunca é o caso. Geralmente, são apenas instâncias específicas que você deseja ignorar.
precisa
1

No MSVC, para suprimir um aviso específico, basta especificar o número do compilador como / wd #. Meu CMakeLists.txt contém esse bloco:

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 ()

Agora, não posso dizer o que exatamente / wd4512 / wd4702 / wd4100 / wd4510 / wd4355 / wd4127 significa, porque não presto atenção à MSVC por três anos, mas suprimem avisos super-atlânticos que não influenciam o resultado.

Bwana The Master
fonte
0

Eu já vi esse estilo sendo usado:

if (when || who || format || data || len);
Iustin
fonte
14
Hum. Não posso dizer que gosto disso, pois isso pressupõe que todos os parâmetros envolvidos possam ser convertidos em um bool.
Suma
1
Essa não é realmente uma boa convenção, embora o compilador quase certamente a otimize, não está realmente claro o que está acontecendo e pode confundir os verificadores de fonte estática. melhor usar uma das outras sugestões aqui IMHO.
ideasman42
1
Não acredito que ainda estou recebendo respostas para isso. A pergunta afirmou que era para C. Sim, em outro idioma isso não funcionaria.
Iustin # 17/13
2
Eu não usaria, mas +1 para o fator novidade.
mgalgs
2
verificar a verdade das variáveis ​​pode dar avisos, para estruturas. por exemplo. struct { int a; } b = {1}; if (b);O GCC adverte used struct type value where scalar is required,.
ideasman42
-1

Para o registro, eu gosto da resposta de Jó acima, mas estou curioso sobre uma solução usando apenas o nome da variável em uma declaração "não faça nada":

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

Claro, isso tem desvantagens; por exemplo, sem a nota "não utilizada", parece um erro e não uma linha de código intencional.

O benefício é que nenhum DEFINE é necessário e elimina o aviso.

Existe algum desempenho, otimização ou outras diferenças?

Dr. Pessoa Pessoa II
fonte
2
Eu também usei isso com o MSVC, mas o GCC gera um aviso "declaração sem efeito". Portanto, a solução de Jó é o caminho a percorrer.
Dmitrii Semikin
Essa abordagem ainda gera um aviso no XCode
MOK9 5/19/19