Fundo
Nota: Isso não é importante para a questão
Tenho algumas macros que agem como uma versão um pouco mais geral de atributos, que anexo a funções. Dependendo do compilador e da versão do compilador, elas se expandirão para um atributo (por exemplo, __attribute__((nonnull))
) ou um aviso (por exemplo, _Pragma("message \"nonnull attribute unavailable\"")
). Como as macros de atributos podem estar em qualquer ordem, isso pode levar a que sejam misturadas (por exemplo, aviso atributo atributo aviso aviso).
O resultado é que posso ter um código como o seguinte:
Amostra
#pragma message "one"
__attribute__((cold))
#pragma message "two"
__attribute__((noreturn))
#pragma message "three"
void test(void);
Emitir
Executando clang
, este código de exemplo compila perfeitamente, imprimindo as três mensagens conforme o esperado.
input.c:1:9: warning: one [-W#pragma-messages]
#pragma message "one"
^
input.c:3:9: warning: two [-W#pragma-messages]
#pragma message "two"
^
input.c:5:9: warning: three [-W#pragma-messages]
#pragma message "three"
^
Executar gcc
, no entanto, me dá um erro no segundo #pragma
. Se eu comentar isso, recebo um erro no terceiro #pragma
.
input.c:1:9: note: ‘#pragma message: one’
1 | #pragma message "one"
| ^~~~~~~
input.c:3:9: error: expected identifier or ‘(’ before ‘#pragma’
3 | #pragma message "two"
| ^~~~~~~
input.c:1:9: note: ‘#pragma message: one’
1 | #pragma message "one"
| ^~~~~~~
input.c:5:9: error: expected identifier or ‘(’ before ‘#pragma’
5 | #pragma message "three"
| ^~~~~~~
Com a experimentação, parece que gcc
não aceita nenhuma #pragma
diretiva depois de um __attribute__
.
Exemplo reproduzível
Descomentar #pragma
causa um erro reproduzível no GCC v11.4.0
__attribute__((nonnull))
// #pragma message "this is an error"
void test(void);
Pergunta
Existe alguma correção ou solução que me permita misturar as diretivas #pragma
and em , assim como permite?__attribute__
gcc
clang