Что я могу сделать с предупреждением GNU ld 'legacy __sync_synchronize'? - PullRequest
0 голосов
/ 02 января 2019

У меня есть некоторый код 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 ]

0 голосов
/ 15 января 2019

Было бы лучше, если бы вы подождали ответа на https://devkitpro.org/viewtopic.php?f=13&t=8822#p16213, а не спрашивали на сайте, где большинство людей не знакомы с devkitARM.

ТЛ; др; скомпилируйте ваш код с -fno-threadsafe-statics и не беспокойтесь об этом.

0 голосов
/ 14 января 2019

Вы получаете предупреждение компоновщика, сгенерированное этой версией newlib, чтобы сообщить вам, что ваше приложение имеет вызовы __sync_synchronize и что нет реализации этой функции, которая фактически синхронизируется.Реализация этой функции в newlib - это заглушка, которая ничего не делает (возможно, она просто существует, чтобы гарантировать отсутствие неопределенных ссылок на эту функцию).

Эти вызовы, вероятно, поступают из libstdc++.so, как GCC на ARMбудет выдавать вызовы __sync_synchronize для некоторых элементарных операций, которые происходят внутри библиотеки (например, обновления счетчика ссылок в std::string или shared_ptr объектах).

Чтобы получить рабочий __sync_synchronize, который делает правильную атомикувам, вероятно, нужно указать ссылку на libatomic (используя -latomic), в которой будет реализована эта функция.Поскольку вы не ссылаетесь на это, вы получаете запасную реализацию заглушки в newlib.Если вам не нужна синхронизированная атомика (потому что ваше приложение является однопоточным и никогда не пытается обновить атомику в обработчиках сигналов), тогда я думаю, что вы можете игнорировать предупреждение.

Другой вариант - использовать сборкуlibstdc ++., так что в явном виде отключает все потоки, и теоретически не будет никаких ссылок на __sync_synchronize.Но эта сборка libstdc ++. Может быть использована только для однопоточных приложений.Используемая сейчас сборка может использоваться как для однопоточного, так и для многопоточного кода (даже если вы получаете это предупреждение, которое не очень актуально для однопоточных случаев).

...