Что я могу сделать с предупреждением GNU ld 'legacy __sync_synchronize'?
У меня есть некоторый код C++, который использует локальную область, объект времени жизни программы, например
void testFunction(int arg) {
static Tested tested(0);
tested.use(arg);
}
который прекрасно работал со старыми версиями GCC. С GCC 8.2.0 я получаю удивительное предупреждение во время ссылки:
предупреждение: используется устаревшая совместимая __sync_synchronize. Не подходит для многопоточных приложений
Он указывает строку, определяющую проверенный, и действительно есть вызов __sync_synchronize(), который был сгенерирован компилятором. Я предполагаю, что это необходимо для того, чтобы никакие два потока не могли запустить инициализирующий код одновременно и чтобы ленивая инициализация давала такой же результат, как если бы была инициализация во время загрузки.
Проблема воспроизводится с этой реализацией класса Tested:
class Tested {
int sum;
public:
Tested(int init) : sum(init) {}
void use(int arg) {
sum += arg;
}
int current() const {
return sum;
}
};
Ожидается, что этот код будет работать на монопоточной встроенной платформе.
Правильно ли я верю, что предупреждение не имеет отношения к мне?
Что я могу сделать (помимо прекращения использования статического объекта), чтобы избавиться от предупреждающего сообщения?
2 ответа
Вы получаете предупреждение компоновщика, генерируемое этой версией newlib, чтобы сообщить вам, что ваше приложение имеет вызовы __sync_synchronize
и что нет реализации той функции, которая фактически синхронизируется. Реализация этой функции в newlib - это заглушка, которая ничего не делает (возможно, она просто существует, чтобы гарантировать отсутствие неопределенных ссылок на эту функцию).
Эти звонки, вероятно, приходят изнутри libstdc++.so
, как GCC на ARM будет излучать звонки __sync_synchronize
для некоторых элементарных операций, которые происходят внутри библиотеки (например, обновления счетчиков ссылок в std::string
или же shared_ptr
объекты).
Чтобы получить работу __sync_synchronize
что делает атомику правильной, вам, вероятно, нужно сослаться на libatomic
(с помощью -latomic
) который будет иметь реализацию этой функции. Поскольку вы не ссылаетесь на это, вы получаете запасную реализацию заглушки в newlib. Если вам не нужны синхронизированные атомы (потому что ваше приложение является однопоточным и никогда не пытается обновить атомики в обработчиках сигналов), тогда я думаю, что вы можете проигнорировать предупреждение.
Другим вариантом было бы использовать сборку libstdC++., Чтобы явно отключить все потоки, и теоретически это не будет иметь никаких ссылок на __sync_synchronize
, Но эта сборка libstdC++. Может быть использована только для однопоточных приложений. Используемая вами сборка может использоваться как для однопоточного, так и для многопоточного кода (даже если вы получаете это предупреждение, которое не очень актуально для однопоточных случаев).
Для вас было бы лучше подождать ответа по адресу https://devkitpro.org/viewtopic.php?f=13&t=8822#p16213, а не спрашивать на сайте, где большинство людей не знакомы с devkitARM.
ТЛ; др; скомпилируйте ваш код с -fno-threadsafe-statics и не беспокойтесь об этом.