Секретом является одно правило определения.Если строки скрыты, вы можете получить несколько (личных) копий строки для каждого изображения.
В идеале вы должны настроить и использовать все, чтобы оно могло функционировать с использованием одного правила определения,тогда вы могли бы включить приватные внешние функции в качестве оптимизации (что может быть не во всех отношениях, особенно в двоичном формате).Вы бы предпочли этот подход, потому что он следует модели стандарта.
Для быстрого обновления по ODR:
// somewhere.hpp
namespace MON {
inline int cas(const int*,const int*,int*) {
return dah_dum();
}}
// elsewhere.hpp
namespace MON {
inline int cas(const int*,const int*,int*) {
return dum_dah();
}}
Любая ссылка int MON::cas(const int*,const int*,int*)
, которая не является полностью или частично встроенной, но является функциейвызов int MON::cas(const int*,const int*,int*)
может привести к использованию любого определения независимо от того, какое определение было видимым для TU.Ровно одно определение сохраняется компоновщиком, и предполагается, что все определения равны.Это важно, потому что ваши двоичные размеры взорвались бы, если бы каждое определение, на которое есть ссылка и видимое, дало бы копию для каждого перевода .
Если это «работает» при использовании правил ODR, тогда это вероятночто у вас есть несколько определений данного символа в ваших объектных файлах, и что вы в конечном итоге ссылаетесь на разные определения из-за настроек компилятора.Если вы объявили inline, который не является статичным или находится в анонимном пространстве имен, определение должно быть одинаковым для всех исходных файлов.
Если вы смешиваете это с C TU, хорошо ... у него другоеправила связывания, которые только усложняют ситуацию.