にわかプラス

にわかが玄人になることを夢見るサイトです。社会や国際のトレンド、プログラミングや電子工作のことについて勉強していきたいです。

undefined reference to `__sync_synchronize'をfno-threadsafe-statics で解決した話

sponsor

自分の書いたコードをコンパイルすると、うまく通ればちょっと嬉しい気持ちになれる。
反対に、出されたエラーが見慣れないものだと一気に困ったことになる。困惑と悲しみ、怒り、様々な感情が押し寄せてくる。
とくにコンパイラの出すエラーは見慣れないものが多く、本当に大変。。。

出会ったエラーとその対処法を残すことで、皆様と未来の自分に役立ちたい。

C++で以下のエラーが出るときの対処法。

undefined reference to `__sync_synchronize'

対処法

コンパイルオプションに以下を追加。

-fno-fthreadsafe-statics

エラーの意味

class Car(){
    Car(){
        static Body body ;
    }
}

複数スレッドで同時にCarが呼ばれると、StaticなBodyオブジェクトの生成が複数回行われる可能性がある。
Staticなオブジェクトは1度しか生成されないため、未定義の影響をプログラム全体に与えてしまうことになる。
そこでコンパイラが賢く、ローカルStaticオブジェクトをスレッドセーフ化するため、 「メモリバリア」というものを実施してくれる。

「メモリバリア」を実施するために、コンパイラがsync_synchronize()関数を呼び出すが、それが見つからないというエラー 。

起こった環境はARMのクロスコンパイル環境 arm-none-eabi-gcc 8.3.0. 。
おそらくこのクロスコンパイル環境自体のバグっぽい。

StackOverFlowではGCC 8.2.0でも起こっているみたい。
c++ - what can I do about GNU ld 'legacy __sync_synchronize' warning? - Stack Overflow

コンパイルオプション"-fno-fthreadsafe-statics"の意味

コンパイル時に、静的オブジェクトをスレッドセーフ化する、 「メモリバリア」を実施しないようにする。

"-fno-fthreadsafe-statics"についての詳しい説明サイト
g++ の -fthreadsafe-statics ってオプション知ってます? - memologue

おわりに

今回はコンパイラを変えられないときの暫定的な対処法。

このオプションを付けて他に問題がなければいいが、クロスコンパイル環境自体のバグの場合は環境のバージョンを上げるなどして根本的な解決をしたい。