Erro das Ferramentas de Vinculador LNK2005

symbol já definido no objeto

O símbolo symbol foi definido mais de uma vez.

Esse erro é seguido pelo erro fatal LNK1169.

Possíveis causas e soluções

Geralmente, esse erro significa que você quebrou a regra de uma definição, que permite apenas uma definição para qualquer modelo, função, tipo ou objeto usado em um determinado arquivo de objeto e apenas uma definição em todo o executável para objetos ou funções externamente visíveis.

Aqui estão algumas causas comuns para esse erro.

  • Esse erro pode ocorrer quando um arquivo de cabeçalho define uma variável. Por exemplo, se você incluir esse arquivo de cabeçalho em mais de um arquivo de origem em seu projeto, isso resultará em um erro:

    // LNK2005_global.h
    int global_int;  // LNK2005
    

    Entre as soluções possíveis estão:

    • Declare a variável extern no arquivo de cabeçalho extern int global_int;, depois defina-a e, opcionalmente, inicialize-a em um e apenas um arquivo de origem: int global_int = 17;. Essa variável agora é um global que você pode usar em qualquer arquivo de origem declarando-a extern, por exemplo, incluindo o arquivo de cabeçalho. Recomendamos essa solução para variáveis que precisam ser globais, mas uma boa prática de engenharia de software minimiza variáveis globais.

    • Declare a variável static: static int static_int = 17;. Isso restringe o escopo da definição ao arquivo de objeto atual e permite que vários arquivos de objeto tenham uma cópia própria da variável. Não recomendamos que você defina variáveis estáticas em arquivos de cabeçalho devido ao potencial de confusão com variáveis globais. Prefira mover definições de variáveis estáticas para os arquivos de origem que as usam.

    • Declare a variável selectany: __declspec(selectany) int global_int = 17;. Isso orienta o vinculador para escolher uma definição para uso por todas as referências externas e descartar o restante. Essa solução às vezes é útil ao combinar bibliotecas de importação. Caso contrário, não recomendamos isso como uma forma de evitar erros do vinculador.

  • Esse erro pode ocorrer quando um arquivo de cabeçalho define uma função que não é inline. Se você incluir esse arquivo de cabeçalho em mais de um arquivo de origem, obterá várias definições da função no executável.

    // LNK2005_func.h
    int sample_function(int k) { return 42 * (k % 167); }  // LNK2005
    

    Entre as soluções possíveis estão:

    • Adicione a palavra-chave inline à função:

      // LNK2005_func_inline.h
      inline int sample_function(int k) { return 42 * (k % 167); }
      
    • Remova o corpo da função do arquivo de cabeçalho e deixe apenas a declaração, depois implemente a função em apenas um arquivo de origem:

      // LNK2005_func_decl.h
      int sample_function(int);
      
      // LNK2005_func_impl.cpp
      int sample_function(int k) { return 42 * (k % 167); }
      
  • Esse erro também poderá ocorrer se você definir funções membro fora da declaração de classe em um arquivo de cabeçalho:

    // LNK2005_member_outside.h
    class Sample {
    public:
        int sample_function(int);
    };
    int Sample::sample_function(int k) { return 42 * (k % 167); }  // LNK2005
    

    Para corrigir esse problema, mova as definições de função membro para dentro da classe. As funções membro definidas dentro de uma declaração de classe são embutidas implicitamente.

    // LNK2005_member_inline.h
    class Sample {
    public:
        int sample_function(int k) { return 42 * (k % 167); }
    };
    
  • Esse erro poderá ocorrer se você vincular mais de uma versão da biblioteca padrão ou CRT. Por exemplo, se você tentar vincular as bibliotecas CRT de varejo e depuração, ou as versões estáticas e dinâmicas de uma biblioteca ou duas versões diferentes de uma biblioteca padrão ao seu executável, esse erro poderá ser relatado muitas vezes. Para corrigir esse problema, remova todas exceto uma cópia de cada biblioteca do comando de link. Não recomendamos que você misture bibliotecas comerciais e de depuração, ou versões diferentes de uma biblioteca, no mesmo executável.

    Para orientar o vinculador a usar bibliotecas diferentes dos padrões, na linha de comando, especifique as bibliotecas a serem usadas e use a opção /NODEFAULTLIB para desabilitar as bibliotecas padrão. No IDE, adicione referências ao seu projeto para especificar as bibliotecas a serem usadas e, em seguida, abra a caixa de diálogo Páginas de Propriedades do projeto e na página Vinculador, na página de propriedades Entrada, defina Ignorar Todas as Bibliotecas Padrão ou Ignorar Bibliotecas Padrão Específicas para desabilitar as bibliotecas padrão.

  • Esse erro poderá ocorrer se você misturar o uso de bibliotecas estáticas e dinâmicas ao usar a opção /clr. Por exemplo, esse erro poderá ocorrer se você criar uma DLL para uso no executável que vincula no CRT estático. Para corrigir esse problema, use apenas bibliotecas estáticas ou apenas bibliotecas dinâmicas para todo o executável e para todas as bibliotecas que você criar para usar no executável.

  • Esse erro poderá ocorrer se o símbolo for uma função empacotada (criada compilando com /Gy) e tiver sido incluído em mais de um arquivo, mas alterado entre compilações. Para corrigir esse problema, recompile todos os arquivos que incluem a função empacotada.

  • Esse erro poderá ocorrer se o símbolo for definido de maneira diferente em dois objetos membros em bibliotecas diferentes e ambos os objetos membros forem usados. Uma maneira de corrigir esse problema quando as bibliotecas estão estaticamente vinculadas é usar o objeto membro de apenas uma biblioteca e incluir essa biblioteca primeiro na linha de comando do vinculador. Para usar ambos os símbolos, você precisa criar uma maneira de distingui-los. Por exemplo, se você puder criar as bibliotecas da origem, poderá encapsular cada biblioteca em um namespace exclusivo. Como alternativa, você pode criar uma biblioteca wrapper que usa nomes exclusivos para encapsular referências a uma das bibliotecas originais, vincular a nova biblioteca à biblioteca original e, em seguida, vincular o executável à sua nova biblioteca em vez da biblioteca original.

  • Esse erro poderá ocorrer se uma variável extern const for definida duas vezes e tiver um valor diferente em cada definição. Para corrigir esse problema, defina a constante apenas uma vez ou use namespaces ou definições enum class para distinguir as constantes.

  • Esse erro poderá ocorrer se uuid.lib for usado em combinação com outros arquivos .lib que definam GUIDs (por exemplo, oledb.lib e adsiid.lib). Por exemplo:

    oledb.lib(oledb_i.obj) : error LNK2005: _IID_ITransactionObject
    already defined in uuid.lib(go7.obj)
    

    Para corrigir esse problema, adicione /FORCE:MULTIPLE às opções de linha de comando do vinculador e verifique se uuid.lib é a primeira biblioteca mencionada.