*GCC [#fdd7f1aa]

以下ではいろいろなバージョンについての記述が入り乱れてしまいました。

**はじめに [#d42582a6]

現在の GCC は GNU Compiler Collection の略です。~
昔の GCC は GNU C Compiler の略でした。~
途中から Cygnus 社(後 Red Hat に吸収)が中心となって EGCS プロジェクトと称して新しい GCC の開発に着手し,現在では EGCS プロジェクトが正式な GCC 開発元となっています。~
EGCS であったころも C コンパイラのコマンド名は gcc でした。~
EGCS と GCC はバージョンの違いと考えればいいでしょう。~

:Arch Linux での gcc -v の表示|
gcc バージョン 4.9.1 20140903 (prerelease) (GCC)

GCC 4.8.1 からは C++ コンパイラが ISO/IEC 14882:2011 (C++11)([[Stroustrupの第4版:http://www.stroustrup.com/4th.html]]に相当)に準拠しました。~
これだけの理由からも 4.8.1 以降にアップグレードする意味があると思います。~
ただ,従来コンパイルできていたものがコンパイルできなくなる可能性は十分にあります。~
特にLinuxカーネルのコンパイルには注意が必要です(これはC++とは無関係)。~

**リリース情報 [#g49d1e66]

***GCC [#eb72abd6]

-http://gcc.gnu.org/releases.html

***GCC (Arch Linux) [#qf1d9c14]
-https://www.archlinux.org/packages/?sort=&q=The+GNU+Compiler+Collection

**インストール? [#v56bd0c2]

一般の Linux ディストリビューションには GCC のパッケージが提供されていますが,インストール時に「開発環境」を選択しないとインストールされないかもしれません。~
GCC をソースからコンパイルする必要はありません(そもそもコンパイルには GCC が必要です)。~

Arch Linux には最新版の GCC が入っています。~

以下では,Linux で GCC をソースからコンパイルしてインストールする方法を解説します。

**準備 [#ad59fe2d]

インストールに先立って,最近の [[binutils:http://www.ring.gr.jp/pub/GNU/binutils/]]
にアップグレードします。
binutils とはアセンブラ(as)やローダ(ld)の類です。

 $ ld -v
 GNU ld (GNU Binutils) 2.23.2

これが古いと,コンパイルは通っても,C++
でコンパイルしたものを実行するときに次のようなエラーが出ます:

 error in loading shared libraries: /usr/local/lib/libstdc++.so.3: undefined symbol: __dso_handle

binutils は rpm で入れてもいいでしょうし,ソースからコンパイルしても簡単です:

 ./configure
 make
 make install

また,info ファイルも必要なら,makeinfo (texinfo) も最新のものにしておきます。
Ring サーバなら [[/pub/GNU/texinfo/:http://www.ring.gr.jp/pub/GNU/texinfo/]]
にありますので,最新の texinfo を ./configure,make,make install します。

**Dwarf error [#q843ee36]

3.1 にしたところ,tmpnam,tempnam,mktemp を使っているものの make
で次のエラーが出るようになりました(次は qpopper-4.0.4):

 /usr/bin/ld: Dwarf Error: Invalid or unhandled FORM value: 14.
 ../common/libcommon.a(maillock.o): In function `Qmaillock':
 /usr/local/src/qpopper4.0.4/common/maillock.c:278: the use of `tempnam' is dangerous, better use `mkstemp'
 collect2: ld はステータス 1 で終了しました

昔のものでは次のようになるだけです。

 ../common/libcommon.a(maillock.o): In function `Qmaillock':
 /usr/local/src/qpopper4.0.4/common/maillock.c:278: the use of `tempnam' is dangerous, better use `mkstemp'

[[ここ:http://gcc.gnu.org/ml/gcc/2002-02/msg00965.html]]
によれば,binutils をもっと新しくする必要があるようです。
binutils-2.12.1 に入れ替えました(この binutils 自体も gcc-3.1 + binutils-2.10.1
では駄目で,古い gcc-2.95.3 でコンパイルしました)。

結局,最新の gcc は最新の binutils と組み合わせて使うべきということでしょう。

**組み立て [#rcaefdd7]

RingServer の
[[/pub/GNU/gcc/:http://www.ring.gr.jp/pub/GNU/gcc/]]
または
[[/pub/lang/egcs/releases:http://www.ring.gr.jp/pub/lang/egcs/releases]]
の中にある gcc-4.9.1.tar.bz2 といったもの(番号の一番新しいもの)をダウンロードします。~

C++ のインクルードファイルは,4.9.1 では /usr/local/include/c++/4.9.1/
といったところに入ります。

 cd /usr/local/src
 tar xvf ...../gcc-4.9.1.tar.bz2
 mkdir gccobj
 cd gccobj
 ../gcc-4.9.1/configure --enable-languages=c,c++,ada,fortran,go,objc,obj-c++
 make bootstrap
 make install

~--enable-languages には必要に応じて c, c++, ada, fortran, go, objc, obj-c++ を指定します。

~--enable-shared は現在ではデフォルトでオンになっています。

これで /usr/local 以下にインストールされました。

Linux の場合,/etc/ld.so.conf に /usr/local/lib という行がなければ追加し,

 ldconfig

と打ち込みます。

バージョンを確かめてみましょう(/usr/local/bin が /usr/bin より先にパスにあるとします)。
以下は 4.9.1 のものです。

 $ gcc --version
 gcc (GCC) 4.9.1 20140903 (prerelease)
 $ gcc -v
 組み込み spec を使用しています。
 COLLECT_GCC=gcc
 COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-unknown-linux-gnu/4.9.1/lto-wrapper
 ターゲット: x86_64-unknown-linux-gnu
 configure 設定: /build/gcc/src/gcc-4.9-20140903/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-gnu-unique-object --enable-linker-build-id --enable-cloog-backend=isl --disable-isl-version-check --disable-cloog-version-check --enable-lto --enable-plugin --enable-install-libiberty --with-linker-hash-style=gnu --disable-multilib --disable-werror --enable-checking=release
 スレッドモデル: posix
 gcc バージョン 4.9.1 20140903 (prerelease) (GCC) 


gcc -std=c11 hoge.c とすると ISO C11 になります。

C++ は g++ hoge.cc でコンパイルできます。

**任意の型の文字列? [#lbffe22f]

新しい GCC では std::basic_string<unsigned char>
のようなことができなくなったそうです([[Making strings of arbitrary character types:http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5]])。

**C/C++ での数値計算のヒント [#ud302bf3]

以下は一部古いままです。

最適化オプション -O,-O2,-O3
を与えると,数字が大きくなるほど強力な最適化を行います。
数値計算で最適化オプションを与えないことはまずありえませんが,
強すぎる最適化でコンパイラのバグ等により結果が不正確になることがありえます。

次のようなオプションを与えると各 CPU に固有な命令を生成します。 (→ [[Intel 386 and AMD x86-64 Options:https://gcc.gnu.org/onlinedocs/gcc/i386-and-x86-64-Options.html]])

:-march=native|
コンパイル環境のマシンの CPU を自動的に判別
:-march=haswell|
Intel Haswell CPU
:-march=bdver3|
AMD Steamroller

//~-march=native というのもできたようです。

他に速度に関連するオプションに次のものがあります。

:-malign-double|
double, long double, long long の計算が Pentium で若干速くなる
:-funroll-loops|
ループを展開する
:-fno-math-errno|
errno をセットしない(多少速くなる)
:-ffast-math|
エラーチェックをさぼる(お勧めしません)
:-fomit-frame-pointer|
フレームポインタをレジスタから追い出す

その他のオプション:

:-mieee-fp|
実数の比較を IEEE 754 通りに行う

精度については,x86 では80ビットの long double
が使えますし,最後に l(エル)の付いた名前の long double
版の関数が使えます。

C

 #include <stdio.h>
 #include <math.h>
 int main()
 {
     printf("%.30g\n", 4 * atan(1.0));
     printf("%.30Lg\n", 4 * atanl(1.0));
     return 0;
 }

数学関数を使っているので

 gcc hogehoge.c -lm

のように -lm オプションを付けてコンパイルします。
結果は次の通りです(太字は不正確な部分):

 3.14159265358979311599796346854
 3.14159265358979323851280895941

C++

 #include <iostream>
 #include <iomanip>
 #include <cmath>
 using namespace std;
 int main()
 {
     cout << setprecision(30);
     cout << 4 * atan(1.0) << endl;
     cout << 4 * atan(1.0L) << endl;
     cout << 4 * atanl(1.0) << endl;
 }

結果は次の通りです(太字は不正確な部分):

 3.14159265358979312
 3.141592653589793238513
 3.141592653589793238513

cout << setprecision(30); がないと 3.14159 になります。

>[蛇足]
正確なπの値は 3.14159265358979323846... で,これを四捨五入した 3.1415926535897932385
まで正しいとしていましたが,最後の 5 まで正しくない桁とするかどうか悩むところです。
最後の 5 は灰色,ということで,灰色にしてみました。

Intel 系の FPU control word を制御するには次のようにします(glibc-2.1 の場合)。

 #include <fpu_control.h>
 
 main()
 {
 //  fpu_control_t cw = 0x037f;  // default
 //  fpu_control_t cw = 0x137f;  // infinity control (8087 and 80287 only)
 //  fpu_control_t cw = 0x127f;  // round to double
     fpu_control_t cw = 0x1372;  // interrupt on invalid/zero-divide/overflow
     _FPU_SETCW(cw);
 
     ...
 }

各ビットの意味は /usr/include/fpu_control.h に載っています。

この項の参考リンク

-[[William Kahan:http://http.cs.berkeley.edu/~wkahan/]]
のページからダウンロードできるペーパーはたいへんおもしろい。
-[[How to optimize for the Pentium family of microprocessors:http://www.agner.org/assem/pentopt.htm]] (Agner Fog)
-[[Branch prediction in the Pentium family:http://x86.ddj.com/articles/branch/branchprediction.htm]] (Agner Fog)

**おまけ [#b168f48b]

~*.h を Emacs で C++ モードで書くには,頭に // -*- C++ -*- のようなコメントを付けておきます。

// f77 じゃ駄目、f90 を使いたい!
// [[Veridian VAST/f90 Linux Fortran 90 compiler:http://www.psrv.com/lnxf90.html]]
// は f90 ソースを f77 に変換して g77 でコンパイルしてくれます。
// 個人利用は無料です。
// ……残念ながら公開中止だそうです。

SJISで出力したい?
http://www4.ocn.ne.jp/~sysgi/sjispat.htm
にパッチが公開されています。

**コメント [#l09fa82d]

-Linux なら [[g95:http://www.g95.org/]] が使えると思うのですが、いかがでしょうか?
-まだ使っていません。次期GCCのgfortranに期待しているのですが -- 奥村 &new{2004-10-04 (月) 07:59:06};
- maillock.o(.text+0x1d2): warning: tempnam() possibly used unsafely; consider using mkstemp() --  &new{2006-06-19 (月) 20:16:26};
- GCC で、Fortran 2008/2003 がサポートされているようです(「[[Fortran - TeX Wiki:http://oku.edu.mie-u.ac.jp/~okumura/texwiki/?Fortran]]」より)。 --  &new{2014-09-20 (土) 11:32:35};

#comment