Что, если переопределить встроенную функцию?

Я провел несколько дней в странной проблеме и наконец обнаружил, что в проекте были две встроенные функции с одной и той же сигнатурой, и они вызвали проблему. Для упрощения ситуации приведем пример: два файла cpp:

a.cpp

#include <iostream>

void b();

inline void echo()
{
    std::cout << 0 << std::endl;
}

int main()
{
    echo();
    b();
    return 0;
}

и b.cpp

#include <iostream>

inline void echo()
{
    std::cout << 1 << std::endl;
}

void b()
{
    echo();
}

Обратите внимание, что встроенные функции echo имеют одинаковые подпись но другой инвентарь. Скомпилируйте и запустите

g++ a.cpp b.cpp -o a.out && ./a.out

Или вот так

g++ a.cpp -c
g++ b.cpp -c
g++ a.o b.o -o a.out
./a.out

Он напечатает 0 0 . (Я использовал для этого g ++ 4.6.1, и я тестировал с clang ++ 2.9, результат тот же)

Этого не произойдет, если включить оптимизацию, например

g++ -O3 a.cpp b.cpp -o a.out && ./a.out

На этот раз 0 1 .

Мой вопрос в том, что независимо от результата или того, как выполняется компиляция, нет ошибок или даже предупреждений о том, что я определил встроенные функции несколько раз. Что, черт возьми, происходит с компилятором и компоновщиком в такой ситуации?

РЕДАКТИРОВАТЬ:

Взгляните на символы в объектном файле

nm a.o b.o | c++filt

Оба файла имеют запись echo () . Так что я думаю, что проблема возникает во время ссылки. Можно ли сказать, что компоновщик случайным образом выбирает одну реализацию и отбрасывает все остальные?

8
задан neuront 27 July 2011 в 11:30
поделиться