Para fins puramente educacionais, estou tentando escrever exemplos com os componentes "Constructing Function Calls" ( https://gcc.gnu.org/onlinedocs/gcc-13.2.0/gcc/Constructing-Calls.html#index-_005f_005fbuiltin_005fva_005farg_005fpack )
Escrevi um exemplo que incorpora o que aparece na documentação:
#include <stdio.h>
extern int myprintf(FILE *f, const char *format, ...);
extern inline __attribute__((__gnu_inline__)) int myprintf(FILE *f, const char *format, ...)
{
int r = fprintf(f, "myprintf: ");
if (r < 0)
return r;
int s = fprintf(f, format, __builtin_va_arg_pack());
if (s < 0)
return s;
return r + s;
}
int main()
{
myprintf(stdout, "ciao %d\n", 10);
return 0;
}
mas não posso construir
max@jarvis:~/test$ gcc --version
gcc (Ubuntu 13.2.0-4ubuntu3) 13.2.0
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
max@jarvis:~/test$ gcc -std=gnu2x -Wall test1.c -o test1
/usr/bin/ld: /tmp/ccgD1BYT.o: in function `main':
test1.c:(.text+0x27): undefined reference to `myprintf'
collect2: error: ld returned 1 exit status
a versão do gcc é mostrada acima
Onde eu estou errando?
gcc
O nível de otimização padrão é-O0
(nenhum). Inlining não está ativo sem otimização, então:emite uma chamada externa regular para
myprintf
, que não tem definição.Manual GCC: 3.11 Opções que controlam a otimização :
[minha ênfase]
Ajuntar com:
ou superior
-O
e o programa será vinculado e executado conforme o esperado.Você pode comparar o
-O0
assembly , onde não há nenhum vestígiomyprintf
além de uma chamada externa, com o-O1
assembly , onde sua definição embutida é aparente.Consulte mais adiante a seita. 3.11 se desejar saber quais opções específicas de inlining estão habilitadas em cada nível de otimização.
Sua função é
extern inline
, mas você não forneceu uma definição externa para sua função. Seu código é inválido, você forneceu apenasinline
a definição da função.Ao usar,
extern inline
você também deve fornecer uma segunda não definição separadainline
da função. Por estar faltando, seu compilador pode falhar na compilação comundefined reference
essa definição externa da função.Basta remover
inline
. Você também pode removerextern
, pois as funções são implicitamenteextern
. Apenas__attribute__((__gnu_inline__)) int myprintf
, não,extern
nãoinline
.inline
tem um significado muito especial em C. Não use. Você pode estar interessado em pesquisarinline
linkage , em particular O que acontece com uma função inline externa? , Qual é o uso da palavra-chave `inline` em C? , https://en.cppreference.com/w/c/language/inline .Normalmente, nada de especial é necessário.