As funções não utilizadas são otimizadas?

Uma pergunta bastante simples … Compiladores hoje em dia tendem a fazer uma quantidade significativa de otimizações. Eles também removem funções não utilizadas da saída final?

Depende do compilador. O Visual C ++ 9 pode fazer isso – funções static não utilizadas são removidas na fase de compilation (há até mesmo um aviso C4505 para isso), funções não utilizadas com binding externa podem ser removidas na fase de link, dependendo das configurações do vinculador .

O MSVC (o compilador / vinculador do Visual Studio) pode fazer isso se você compilar com /Gy e vincular com /OPT:REF .

O GCC / binutils pode fazer isso se você compilar com -ffunction-sections -fdata-sections e link com --gc-sections .

Não sei sobre outros compiladores.

Como regra geral, a resposta é:

Sim: para funções static não utilizadas.

Não: para funções globalmente disponíveis não utilizadas.

O compilador não sabe se alguma outra unidade de compilation faz referência a ele. Além disso, a maioria dos tipos de módulo de object não permite que as funções sejam removidas após a compilation e também não fornece uma maneira para o vinculador informar se existem referências internas. (O vinculador pode dizer se há outros externos .) Alguns vinculadores podem fazer isso, mas muitas coisas funcionam contra isso.

Obviamente, uma function em seu próprio módulo não será carregada desnecessariamente por nenhum vinculador, a menos que seja parte de uma biblioteca compartilhada. (Porque pode ser referenciado no futuro em tempo de execução, obviamente.)

Muitos compiladores fazem isso, mas isso depende da implementação específica. As compilações de debugging geralmente incluem todas as funções, para permitir que elas sejam chamadas ou examinadas no depurador. Muitos compiladores de sistemas embarcados, por razões que eu não compreendo totalmente (*), includeão todas as funções em um arquivo de object se incluírem qualquer um, mas omitirão inteiramente quaisquer arquivos de object que não sejam usados ​​de forma alguma.

Note que em linguagens que suportam Reflexão (por exemplo, Java, C #, vb.net, etc.) é possível, dado o nome de uma function, criar uma referência a ela em tempo de execução, mesmo que não exista nenhuma referência no código. Por exemplo, uma rotina pode aceitar uma string do console, modificá-la de alguma forma e gerar uma chamada para uma function com esse nome. Não haveria maneira de um compilador ou vinculador saber quais nomes poderiam ser gerados e, portanto, não há como saber quais funções podem ser omitidas com segurança do código. Essa dificuldade não existe em C ou C ++, no entanto, uma vez que não existe uma maneira definida para o código criar uma referência a uma function, variável ou constante sem uma referência explícita existente no código. Algumas implementações podem organizar as coisas de modo que as constantes ou variables ​​declaradas consecutivamente sejam armazenadas consecutivamente, e uma delas pode criar uma referência a uma posteriormente declarada, adicionando um deslocamento a uma declaração anterior, mas o comportamento de tais truques é explicitamente não garantido pelos padrões C ou C ++.

(*) Eu entendo que isso facilita a compilation e a vinculação, mas os computadores de hoje não devem ter problemas para executar algoritmos de compilation e vinculação mais sofisticados do que seria prático em décadas passadas. Se nada mais, um método de pre-compile / pre-link / compile / link de duas passagens poderia na fase de pré-compilation / link produzir uma lista de coisas que são usadas, e então na fase “real” de compilation / link omitir aqueles que não são.

Com o gcc, se você ativar as otimizações, ele poderá remover funções não utilizadas e código morto.

Mais sobre otimizações do gcc podem ser encontradas aqui

Na maior parte do tempo, sim. É frequentemente chamado de stripping de linker.

Quando se trata de MS, é o linker que cuida disso durante a fase de link e o compilador pode avisá-lo sobre funções estáticas não utilizadas (escopo de arquivo). Se você quiser que o vinculador remova funções não usadas, use a opção / OPT: REF :

Em MSVC e com funções globais ou variables, você pode usar __declspec (selectany) .

Ele removerá a function ou variável se ela não estiver sendo referenciada no código se a opção de vinculador / OPT: REF (Otimizações) estiver selecionada.

Tudo depende do compilador e de suas configurações (o código construído em configurações de “debugging” geralmente não é otimizado), juntamente com o próprio código e o alinhamento do planeta.

O essencial é: você não deve se preocupar com essas coisas. Confie no seu compilador.