目次

GCC

Using the GNU Compiler Collection (GCC)
C, C++も参照
binutilsも参照

3.5 Options Controlling C++ Dialect

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

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

3.7 Options to Control Diagnostic Messages Formatting

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とすると改行せずにすべて表示する.

3.8 Options to Request or Suppress Warnings

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 : 浮動小数点を==,!=で比較していると警告を出す。

3.10 Options for Debugging Your Program

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

3.11 Options That Control Optimization

These options control various sorts of optimizations.

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

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

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

という仮定をするので,このオプションを使うときはいろいろ気をつけてやる必要がある.
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

3.15 Options for Linking

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を検索するディレクトリのリストに追加する

3.18.4 ARM Options

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

組み込みC/C++

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用GCC

Arm GNU Toolchain
arm用のGCC

objcopyのバグ

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

stm32用のGCC

CubeCLT

Linker

–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コマンド)の使い方
g++ 最適化オプション
gdbでデバッグするためのgccのデバッグ情報のオプション
GDBを使う為のオプション(GCC)
Make C floating point literals float (rather than double)
コンパイラ(gccコマンド)の使い方
Cortex-M4でFPU演算をするときにつけておきたいgccの警告オプション
gccでCortex-M4のsqrtf()の呼び出しの代わりにFPU命令一発のコードを出力をさせる方法
ARM gcc バッドノウハウ集
GCC と Clang のオプション概要
gccで Wall & Wextra を使っても有効にならない警告
知っていると便利な gcc のオプション