gcc

GCC

This section describes the command-line options that are only meaningful for C++ programs

-fno-rtti : C++のRTTI情報の生成を禁止する.
RTTI(RunTime Type Infomation)は実行時型情報と訳され,プログラムの実行中に型情報を知ることができる.

Traditionally, diagnostic messages have been formatted irrespective of the output device’s aspect (e.g. its width, …). You can use the options described below to control the formatting algorithm for diagnostic messages,

-fmessage-length=n : エラーメッセージの長さをn文字にフォーマットする.デフォルトは72-fmessage-length=0とすると改行せずにすべて表示する.

Warnings are diagnostic messages that report constructions that are not inherently erroneous but that are risky or suggest there may have been an error.

-Wdouble-promotion : 内部の演算にてfloatからdougleへの暗黙の型変換が行われたときに警告
-Wfloat-conversion : 精度が落ちるときの型変換が行われたときの警告.明示的にキャストしていれば問題ない.doubleからfloatへの変換の時など
-Wunsuffixed-float-constants : サフィックス(接尾辞)のない単精度浮動小数点定数があると警告.接尾辞が無いと倍精度として扱われるので注意.

float fdata = 3.14f; // <- この'f'がサフィックス.明示的に単精度浮動小数点定数とコンパイラに伝える

-Wformat,-Wformat=n : printf,scanf等の関数出呼び出しをチェックする.,フォーマット文字列に対して引数や実数の方や個数を確認して違っていたら警告
-Wformat=1-Wformatは同義
-Wformat=0-Wno-formatは同義.型チェックは行わない
-Wfloat-equal : 浮動小数点を==,!=で比較していると警告を出す。

To tell GCC to emit extra information for use by a debugger, in almost all cases you need only to add -g to your other options.

GDBなどでデバッグする時に必要なオプション.

-glevel:デバッグ情報の量を指定.デフォルトでは2.levelの数字が大きいほどデバッグ情報が増える.
-g0:デバッグ情報なし
-g1
-g3

-gdwarf-gdwarf-versionがある時,無効化される?(混同を避けるため)代わりに-glevelを使ってDWARFのデバッグレベルを変更する.

-gdwarf,-gdwarf-version:デバッグ情報をDWARF形式で作成.versionにて2,3,4,5のいずれかを指定.デフォルトでは 4

These options control various sorts of optimizations.

最適化レベルの設定,数字が大きいほど強い最適化がかかる.

-O0:最適化なし
-O1:最適化
-O2:さらに最適化
-O3:かなり最適化
-Os:コードサイズに対して最適化
-Og:デバッグ用に最適化
-Ofast-O3 -ffast-mathと同義

-ffast-math:IEEE574やISOで定義された浮動小数点計算の誤差を気にしなくする(無視する).これらの規格に準拠しなく代わりに計算速度の向上が期待できる.
このオプションを使うと,コンパイラは

  • 引数は非負
  • 浮動小数点がNaNにはならない

という仮定をするので,このオプションを使うときはいろいろ気をつけてやる必要がある.
ARM-CortexMプロセッサでFPUを使う場合のことはFPUも参照
最適化のオプション
なんでGCCはa*a*a*a*a*a を (a*a*a)*(a*a*a) に最適化できないの?っと

-fsingle-precision-constant:浮動小数点のデフォルトを単精度(float)に変更
C言語でのデフォルトの浮動小数点は倍精度(double)であるが,Cortex-M4のFPU単精度なので,変数は意識して型を変更していないと処理が長くなってしまう. 数字たくさん使いまくると全部に回らないことがある.それならコンパイラ側で設定してやってまとめて処理してやったほうがいい.

C: 特定の関数あるいはファイルのコンパイル最適化を無効化

void __attribute__((optimize("O0"))) foo(unsigned char data) {
  // ここのコードは最適化されない
}
 
#pragma GCC push_options
#pragma GCC optimize ("O0")
 
// ここのコードは最適化されない
 
#pragma GCC pop_options
These options come into play when the compiler links object files into an executable output file. They are meaningless if the compiler is not doing a link step.

-nostartfiles:リンク時に標準のスタートアップファイルを使用しない.
-Xlinker optionoptionをリンカに渡す.GCCが認識にないシステム固有のオプションを渡すことが可能.

These options specify directories to search for header files, for libraries and for parts of the compiler:

ヘッダファイルやライブラリのコンパイラのディレクトリを指定する。
-Ldirdirを検索するディレクトリのリストに追加する

These ‘-m’ options are defined for the ARM port:

ARMアーキテクチャ用のオプション

-mthumb:Thumb命令セットを使用するように設定
-mcpu:ターゲットのARMプロセッサを指定.Cortex-M0の場合-mcpu=cortex-m0

事前に定義されたマクロの確認方法,マイコンのファームウェアだと,コンパイラで事前定義されているゆえ,エディタでは手動で反映するものがあったりする.これの確認方法.

# C
 echo | gcc -dM -E -
 echo | clang -dM -E -
 
# C++
 echo | g++ -dM -E -x c++ -
 echo | clang++ -dM -E -x c++ -

gcc のプリプロセッサの定義済みマクロ(Predefined Macros)の確認方法
GCC dump preprocessor defines
ARM用のGCCなら以下のコマンドで出力できる.

# C
 echo | arm-none-eabi-gcc -dM -E -

Cortex-Mコアをビルドするときはそれぞれコアに合わせて事前定義されたマクロが変わるのでチェックしておく

# Arm-Cortex-M4, ハードウェアFPU有効の場合
echo | arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -E -dM -
#define __VFP_FP__ 1
#define __ARM_PCS_VFP 1
#define __ARM_FP 4  // Cortex-M4
#define __ARM_FP 14 // Cortex-M7

__VFP_FP__1で定義されていることが確認できる.ひとまずハードウェアの浮動小数点演算ユニット(FPU)を使うためにはこれが定義されていることがわかればOKだろう.
Predefined compiler macros

GCCには載ってないけど,組み込みでC/C++使うときによく付けるオプション
CubeIDEでC++プロジェクト作ったときに有効にしてあったもののメモ
-fstack-usage : スタックの使用量を解析.
6.6.2 Static Stack Usage Analysis
gccで各関数が使用しているスタックサイズを出力するオプション
-Wstack-usage=n : スタックがn以上になると警告を出す.
-fno-exceptions : 例外処理を無効化.そもそも例外をあまり理解できてないけど,組み込みだと使ってないのか?
Exceptions
-fno-use-cxa-atexit : プログラム終了時、デストラクタを呼ぶための __cxa_atexit の呼び出し(とリンク)を禁止する.組み込みではプログラム終了という概念がない(無限ループ回しているため)不要ということか?

The Best and Worst GCC Compiler Flags For Embedded
Three GCC Flags for Analyzing Memory Usage

リンカのオプション -Wl,–print-memory-usage

Code optimization with Stm32 Cube IDE
Can GNU LD print memory usage by memory space, rather then just as a bulk percentage?
このフラグだけでは、実は正確なメモリ量が表示されない模様。
初期化ありの変数は、.dataというところに格納されるけど、初期値はromに記録されているので、プログラムのが保存されている.textとの総和がromの使用量として正しいことになる。しかし、このフラグだけではこれを考慮してくれないため、リンカスクリプトを少しいじることで正確にromの使用量を把握できる。
Configuring a Linker Script for Accurate Linker Memory Usage Reporting
→ やっと見つけた革新的な設定?みたいな感じで書いてあるけど、STM32にデフォルトで入っているリンカスクリプトは標準でこの書き方になっているっぽい

Arm GNU Toolchain
arm用のGCC

Windows用のGCC 8-2018-q4-majorにおいて,64-bit address 0x4b4fa300000000 out of range for Intel Hex fileというエラーが出る.
どうやらバグの模様.
別バージョンでは対策済み

いろいろ試す36
objcopy.exe: 64-bit address 0x4b4fa300000000 out of range for Intel Hex file

–start-group,–end-group : これに囲まれたライブラリは,オブジェクトの参照が解決するまで循環して検索されるらしい.だけどこの中身での順番も大切なので注意
Why does the order in which libraries are linked sometimes cause errors in GCC?
日記/2010/01/03/ldオプションの--start-group,--end-group
リンクするファイルの順番に注意する.汎用的なライブラリほど後ろに置く必要がある.ライブラリ内で参照している外部の内容(シンボル)は更に後ろに指定されているライブラリから検索するため.
MinGW: リンク時のライブラリ順序

参考文献

  • gcc.txt
  • 最終更新: 2024/10/27
  • by yuqlid