Во-первых, просто чтобы избежать проблемы XY: эта проблема исходит от https://github.com/cnjinhao/nana/issues/445#issuecomment-502080177. Код библиотеки, вероятно, не должен делать такие вещи (полагаясь на создание неиспользуемого глобального объекта), но вопрос больше о том, является ли это допустимым поведением LTO, а не о проблемах с качеством кода.
Минимальный код, демонстрирующий ту же проблему (непроверенный, просто для уменьшения примера):
// main.cpp
#include <lib/font.hpp>
int main()
{
lib::font f;
}
// lib/font.hpp
namespace lib
{
struct font
{
font();
int font_id;
};
}
// lib/font.cpp
#include <lib/font.hpp>
#include <lib/font_abstraction.hpp>
namespace lib
{
font::font()
{
font_id = get_default_font_id();
}
}
// lib/font_abstraction.hpp
namespace lib
{
int get_default_font_id();
void initialize_font();
}
// lib/font_abstraction.cpp
#include <lib/font_abstraction.hpp>
namespace lib
{
static int* default_font_id;
int get_default_font_id()
{
return *default_font_id;
}
void initialize_font()
{
default_font_id = new int(1);
}
}
// lib/platform_abstraction.hpp
namespace lib
{
struct platform_abstraction
{
platform_abstraction();
};
}
// lib/platform_abstraction.cpp
#include <lib/platform_abstraction.hpp>
#include <lib/font_abstraction.hpp>
namespace lib
{
platform_abstraction::platform_abstraction()
{
initialize_font();
}
static platform_abstraction object;
}
Конструкция объекта font
в main.cpp
зависит от инициализации указателя. Единственное, что инициализирует указатель, — это глобальный объект object
, но он не подлежит судебному преследованию — в случае связанной проблемы этот объект был удален LTO. Разрешена ли такая оптимизация? (См. проект C++ 6.6.5.1.2).
Некоторые примечания:
- Библиотека была собрана как статическая библиотека и связана с основным файлом с использованием
-flto -fno-fat-lto-objects
и динамической стандартной библиотеки C++. - Этот пример можно собрать вообще без компиляции
lib/platform_abstraction.cpp
- в таком случае указатель точно не будет инициализирован.
--whole-archive
исправляет это, это проблема с подключением статической библиотеки. При сборке без статической библиотеки это тоже исправляет. Что касается языка-юриста: конструктор — это нормальная функция, ее нельзя оптимизировать, если у нее есть видимые побочные эффекты. - person KamilCuk   schedule 17.06.2019