Existe algum caso em que a falta de um #include
interrompa o software em tempo de execução, enquanto a compilação ainda continua?
Em outras palavras, é possível que
#include "some/code.h"
complexLogic();
cleverAlgorithms();
e
complexLogic();
cleverAlgorithms();
ambos construiriam com sucesso, mas se comportariam de maneira diferente?
#include
d.#include <vld.h>
em uma posição estratégica no seu código. A remoção ou adição desse cabeçalho de VLD não "interrompe" o programa, mas afeta significativamente o comportamento do tempo de execução. Vi o VLD diminuir a velocidade de um programa a ponto de tornar-se inutilizável.Respostas:
Sim, é perfeitamente possível. Tenho certeza de que existem várias maneiras, mas suponha que o arquivo de inclusão contivesse uma definição de variável global chamada de construtor. No primeiro caso, o construtor executaria, e no segundo, não.
Colocar uma definição de variável global em um arquivo de cabeçalho é um estilo pobre, mas é possível.
fonte
<iostream>
na biblioteca padrão faz exatamente isso; se alguma unidade de conversão incluir<iostream>
, ostd::ios_base::Init
objeto estático será construído no início do programa, inicializando os fluxos de caracteresstd::cout
etc., caso contrário, não será.Sim, isso é possível.
Tudo sobre
#include
s acontece em tempo de compilação. Mas, em tempo de compilação, as coisas podem mudar o comportamento em tempo de execução, é claro:some/code.h
:então
Com o
#include
, a resolução de sobrecarga encontra o mais apropriadofoo(int)
e, portanto, imprime em1
vez de2
. Além disso, comoFOO
é definido, ele também imprimeFOO
.São apenas dois exemplos (não relacionados) que vieram à minha mente imediatamente e tenho certeza de que há muito mais.
fonte
Apenas para apontar o caso trivial, as diretivas de pré-compilador:
E depois
É patológico, talvez, mas já tive um caso relacionado:
Parece inócuo. Tenta ligar
std::max
. No entanto, windows.h define max comoSe fosse
std::max
, seria uma chamada de função normal que avalia f () uma vez eg () uma vez. Mas com windows.h, agora ele avalia f () ou g () duas vezes: uma vez durante a comparação e outra para obter o valor de retorno. Se f () ou g () não for idempotente, isso poderá causar problemas. Por exemplo, se um deles for um contador que retorna um número diferente toda vez ...fonte
using namespace std;
e usarstd::max(f(),g());
, o compilador detectará o problema (com uma mensagem obscura, mas pelo menos apontando para o site de chamada).É possível que esteja faltando uma especialização de modelo.
fonte
Incompatibilidade binária, acessando um membro ou, pior ainda, chamando uma função da classe errada:
Uma função usa e está tudo bem:
Trazendo outra versão da classe:
Usando funções em main, a segunda definição altera a definição da classe. Isso leva à incompatibilidade binária e simplesmente trava no tempo de execução. E corrija o problema removendo o primeiro include em main.cpp:
Nenhuma das variantes gera um erro de tempo de compilação ou link.
A situação vice-versa, adicionando um include, corrige a falha:
Essas situações são ainda mais difíceis ao corrigir erros em uma versão antiga do programa ou ao usar um objeto externo library / dll / shared. É por isso que às vezes devem ser seguidas as regras de compatibilidade com versões anteriores binárias.
fonte
Quero ressaltar que o problema também existe em C.
Você pode dizer ao compilador que uma função usa alguma convenção de chamada. Caso contrário, o compilador terá que adivinhar que usa o padrão, diferente do C ++, onde o compilador pode se recusar a compilá-lo.
Por exemplo,
main.c
foo.c
No Linux em x86-64, minha saída é
Se você omitir o protótipo aqui, o compilador assume que você possui
E a convenção para listas de argumentos não especificadas exige que
float
deve ser convertidodouble
para ser aprovado. Então, embora eu tenha dado1.0f
, o compilador o converte1.0d
para passar parafoo
. E de acordo com o Suplemento de processador de arquitetura AMD64 da interface binária de aplicativos do System V, asdouble
falhas são passadas nos 64 bits menos significativos dexmm0
. Masfoo
espera um float e o lê dos 32 bits menos significativos dexmm0
, e obtém 0.fonte