GCC

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

はじめに

現在の 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版に相当)に準拠しました。
これだけの理由からも 4.8.1 以降にアップグレードする意味があると思います。
ただ,従来コンパイルできていたものがコンパイルできなくなる可能性は十分にあります。
特にLinuxカーネルのコンパイルには注意が必要です(これはC++とは無関係)。

リリース情報

GCC

GCC (Arch Linux)

インストール?

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

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

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

準備

インストールに先立って,最近の 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/ にありますので,最新の texinfo を ./configure,make,make install します。

Dwarf error

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'

ここ によれば,binutils をもっと新しくする必要があるようです。 binutils-2.12.1 に入れ替えました(この binutils 自体も gcc-3.1 + binutils-2.10.1 では駄目で,古い gcc-2.95.3 でコンパイルしました)。

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

組み立て

RingServer の /pub/GNU/gcc/ または /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 でコンパイルできます。

任意の型の文字列?

新しい GCC では std::basic_string<unsigned char> のようなことができなくなったそうです(Making strings of arbitrary character types)。

C/C++ での数値計算のヒント

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

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

次のようなオプションを与えると各 CPU に固有な命令を生成します。 (→ Intel 386 and AMD x86-64 Options)

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

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

-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 に載っています。

この項の参考リンク

おまけ

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

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

コメント



Last-modified: 2014-09-20 (土) 11:32:36 (40d)