Classes locais dentro da função não-membro embutida produzem LNK2005 com MSVC2005
-
21-09-2019 - |
Pergunta
Aparentemente, o MSVC2005 falha ao incorporar as funções dos membros das classes locais, o que leva ao LNK2005.
Estou enfrentando esse erro LNK2005 ao compilar o seguinte:
common.h
contente:
inline void wait_what()
{
struct wtf
{
void ffffuuu() {}
} local;
}
foo.cpp
contente:
#include "common.h"
void foo()
{
wait_what();
}
bar.cpp
contente:
#include "common.h"
void bar()
{
wait_what();
}
Conteúdo LNK2005.cpp:
// forward declarations
void foo();
void bar();
int main()
{
foo();
bar();
return 0;
}
A mensagem de erro é:
error LNK2005: "public void __thiscall `void__cdecl wait_what(void)'::`2'::wtf::ffffuuu(void)" (?ffffuuu@wtf?1??wait_what@@YAXXZ@QAEXXZ) already defined in bar.obj
Sobre aulas locais, a ISO IEC 14882-2003 diz:
9.8 Declarações de classes locais
Uma classe pode ser definida dentro de uma definição de função;tal classe é chamada de local aula.O nome de uma classe local é local para o seu escopo envolvente.A classe local está no escopo do escopo envolvente e tem o mesmo acesso a nomes fora da função que a função envolvente.As declarações em uma classe local podem usar apenas nomes de tipos, variáveis estáticas, variáveis e funções externas e enumeradores do escopo envolvente.
Uma função envolvente não tem acesso especial aos membros da classe local;obedece às regras habituais de acesso (cláusula 11).As funções-membro de uma classe local devem ser definidas dentro de sua definição de classe, se forem definidas.
Perdi algo?
Para mim, parece que é um bug do compilador.GCC e MSVC2008 compilam perfeitamente.No entanto, eu me pergunto se eles realmente incorporariam a chamada ou simplesmente descartariam um dos dois símbolos durante a fase de link.Como uma observação interessante, você pode notar que não há chamada para esta função de membro de classe local.
Gostaria de saber se existe uma solução alternativa para o MSVC2005.Tentei pesquisar no MSDN esse problema típico sem muito sucesso:Não consegui nem encontrar uma lista de bugs conhecidos do compilador.
Anexo: LNK2005.zip
Solução
foi um bug no visual studio 2005, foi corrigido no vs 2008
Outras dicas
Parece um bug para mim.Talvez seja por isso que funciona no VS2008.(Aliás, Microsoft, este é um bom motivo para quebrar a dependência do IDE/compilador no Visual Studio.)
Quanto a uma solução alternativa, tente adicionar explicitamente inline
, ou não inlining wait_what
.