Pergunta

Esse código compila, mas não surpreende, falha ao vincular (não é o principal encontrado):

Listagem 1:

void main();

Erro de link: mingw lib libmingw32.a (main.o): main.c :(. Texto+0x106) Referência indefinida a _winmain@16 '

Mas, o código abaixo compila e links bem, com um aviso:

Listagem 2:

void (*main)();

Aviso: 'Main' geralmente é uma função

Perguntas:

  1. Na Listagem 1, o vinculador deveria ter reclamado por falta de "Main". Por que está procurando _winmain@16?

  2. O executável gerado na Listagem 2 simplesmente trava. Qual é a razão?

Obrigado pelo seu tempo.

Foi útil?

Solução

Caso 1. é específico do Windows - o compilador provavelmente gera _WinMain símbolo quando main está adequadamente definido.

Caso 2. - Você tem um ponteiro, mas como variável estática é inicializado para zero, assim o acidente.

Outras dicas

Verdadeiro, main não precisa ser uma função. Isso foi explorado em alguns programas ofuscados que contêm código de programa binário em uma matriz chamada main.

O tipo de retorno de main () deve ser int (não void). Se o vinculador estiver procurando WinMain, pensa que você tem um aplicativo da GUI.

Na maioria dos sistemas de compilação C, não há informações de tipo associadas a símbolos vinculados. Você pode declarar principal como por exemplo:

char main[10];

E o ligante ficaria perfeitamente feliz. Como você observou, o programa provavelmente falharia, você mesmo você inicialmente inicializou o conteúdo da matriz.

Seu primeiro exemplo não define o principal, apenas o declara, daí o erro do vinculador.

O segundo exemplo define principal, mas incorretamente.

Nas plataformas do Windows, a unidade principal do programa é o WinMain se você não configurar o programa como um aplicativo de console. O "@16" significa que está esperando 16 bytes de parâmetros. Portanto, o vinculador ficaria muito feliz com você, desde que você lhe desse uma função chamada Winmain com 16 bytes de parâmetros.

Se você desejado Um aplicativo de console, esta é a sua indicação de que você estragou algo.

Você declarou um ponteiro para função chamado Main, e o vinculador avisou que isso não funcionaria.

A mensagem _Winmain tem a ver com a forma como os programas do Windows funcionam. Abaixo do nível do tempo de execução do C, um executável do Windows tem um Winmain.

Tente redefinindo -o como int main(int argc, char *argv[])

O que você tem é um erro de vinculador. O vinculador espera encontrar uma função com essa "assinatura" - não anulada sem parâmetros

Ver http://publications.gbdirect.co.uk/c_book/chapter10/argudes_to_main.html etc.

Na Listagem 1, você está dizendo "há um main () definido em outras partes do meu código-eu prometo!". É por isso que ele compila. Mas você está deitado lá, e é por isso que o link falha. O motivo pelo qual você obtém o erro WinMain16 ausente é porque as bibliotecas padrão (para o Microsoft Compiler) contêm uma definição para Main (), que chama WinMain (). Em um programa Win32, você definiria o WinMain () e o vinculador usaria a versão da biblioteca de Main () para chamar Winmain ().

Na Listagem 2, você tem um símbolo chamado Main definido, para que o compilador e o vinculador sejam felizes, mas o código de inicialização tentará chamar a função que está no local de "Main", e descobre que realmente não há uma função lá, e batida.

1.) Uma função dependente (compilador/plataforma) é chamada antes que o código no principal seja executado e, portanto, seu comportamento (_init no caso de Linux/Glibc).
2) A falha do código no segundo caso é justificada, pois o sistema não consegue acessar o conteúdo do símbolo main como uma função que realmente é um ponteiro de função, apontando para o local arbitrário.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top