FreeBSD QandA ジャンル別一覧: プログラミング
[管理番号 140] (最終更新 2004/04/09 05:05:18)
Q. プロファイラ・プロファイリングって何ですか? プロファイラの
使い方がわかりません。
A. プログラムの各関数が何回呼ばれ、実行時間がどれくらいかかったか
統計をとることをプロファイリングと言います。プロファイラは
その際に使用するツールです。
プログラムの高速化をしたい場合、手あたり次第に修正するの
ではなく、まずプロファイラで解析し、どこがボトルネックに
なっているか見極めましょう。
以下、C 言語でのプロファイリングの例を紹介します。
[ステップ 1]
プログラムをコンパイルするとき、-pg オプションを付けます。
% cc -pg hoge.c
もし
% cc -pg hoge.c
ld: -lc_p: no match
とエラーなった場合は、/usr/lib/libc_p.a がないと言われて
いますので、基本配布物である proflibs をインストールしま
しょう。
[ステップ 2]
コンパイルしたプログラムを実行します。
% ./a.out
カレントディレクトリに a.out.gmon というファイルが作ら
れているはずです (環境によっては gmon.out かもしれません)。
このファイルには、関数に入るときと出るときの時刻などの
情報が記録されています。
[ステップ 3]
統計結果を表示します。
% gprof a.out a.out.gmon
(略)
% cumulative self self total
time seconds seconds calls ms/call ms/call name
63.9 2.53 2.53 1 2534.18 2733.40 func1 [2]
5.0 3.32 0.20 1 199.22 199.22 func2 [7]
4.3 3.49 0.17 main [1]
3.4 3.63 0.14 664580 0.00 0.00 vfprintf [4]
(略)
func1 が全体の実行時間の 63.9% を占めているのに対し、
func2 は 5.0% であることがわかります。
func1 を 2倍高速化すれば、プログラム全体では 31% の実行
時間削減につながりますが、func2 を 2倍高速化した場合は
2.5% しか削減されません。
これにより、まずは func1 の高速化に着手すべき、という
結論が得られます。より詳細な情報は gprof(1) を参照して
ください。
gprof は、C 言語用のプロファイラです。他の言語でも、プロ
ファイラが用意されているはずです。例えば Perl なら DProf
パッケージを使います (p5-Devel-DProf として port/package
が用意されています)。
[管理番号 147] (最終更新 2001/10/19 21:29:41)
Q. FreeBSD 上で動作する ML (Meta Language) はありますか?
A. 2001年9月初旬の時点で、以下のものが ports に入っています。
詳しくは、それぞれの pkg-comment、pkg-descr ファイルを参照して下さい。
[Standard ML of New Jersey]
ports/lang/sml-nj/
ports/lang/sml-nj-devel/
the SML '97 definition に準拠した実装です。(Standard ML には 1990
年の定義と 1997年の定義の 2種類があり、それぞれ SML '97、SML '90
とも呼ばれます)。
次の Moscow ML の方が軽いそうです。
[Moscow ML]
ports/lang/moscow_ml
1996 年に見直された Standard ML の中心となる言語の実装です。
モジュール機構は Version 2.0 以降で実装されています。
[Caml Light]
ports/lang/caml-light
Standard ML に似た (つまり少し違う) ML 言語です。
[Objective Caml]
ports/lang/ocaml
Caml Light をベースに、クラスに基づいたオブジェクト指向拡張と
Standard ML 風の強力なモジュール機構を加えたものです。
[nML]
ports/lang/nml
Standard ML と Objective Caml を融合した両者の方言です。
Standard ML については
<URL:[moved?] http://cm.bell-labs.com/cm/cs/what/smlnj/sml97.html>
を参照して下さい。
尚、code を書くのに emacs を使用している場合は、ports/lang/sml-mode.el
も役に立つでしょう。
[管理番号 279] (最終更新 2000/12/07 02:36:22)
Q. X Window System(Motifベース)上でビジュアルにGUI構築を行えるようなツー
ルはありますか?
A. 売りものですが、TeleUSE という物があります(けっこうな値段です)。
また、X Inside
<URL:http://www.xinside.com>
の Accelerated MWM FreeBSD を使うと WSM が付いてきますが、これは
どうでしょう。ただし、バグってるので、core を吐いて MWM ごと落ちて
しまうことがあります。
Motif ベースではですが、XForms というライブラリを使えば、fdesign
という GUI 構築ツールが付いてきます。フリーです。XForms はホーム
ページがあります。
C ではなく、Tcl/Tk ですが、Sun が SpecTcl なる物を開発しています。
結果の外見はほぼ Motif です。
<URL:ftp://ftp.scriptics.com/pub/tcl/guitools/SpecTcl1.1.tar.gz>
Tcl 物で、XF という物もあります。
Windows95上の Boaland Latteや Microsoft J++などの Java 開発環境で
クロス開発して、UNIX の Java 環境(例えば Netscape)で動作させる方法も
あります。
[管理番号 286] (最終更新 1999/02/17 23:58:45)
Q. FreeBSDでI/Oポートを直接制御するには、どうするのでしょうか?
A. /dev/ioをオープンすると、そのプロセスは直接I/O命令を使えるようにな
ります。
[管理番号 321] (最終更新 2000/11/08 02:04:11)
Q. FreeBSD で動く JDK (Java 環境) はありませんか?
A. まずは
FreeBSD Java Project
<URL:http://www.FreeBSD.org/java/>
ミラーサイト
<URL:http://www.jp.FreeBSD.org/www.FreeBSD.org/java/>
日本語訳
<URL:http://www.jp.FreeBSD.org/www.FreeBSD.org/ja/java/>
を御覧下さい。ここから JDK をダウンロードできます。
また、
<URL:[BROKEN!] http://www.ongs.net/daichi/java/index.shtml>
の「FreeBSD Java 入門/導入」も参考になるでしょう。
[管理番号 329] (最終更新 2001/08/12 05:25:00)
Q. perl スクリプトに実行許可属性を付けて
% ./foo.pl
としたときと
% perl foo.pl
の場合で挙動が異なることがあります。
A. 前者と後者で起動される perl(1) のパス(とバージョン)が異なっているためです。
前者の形式でスクリプトが実行されると、Unix はスクリプトの1行目を見て
どのプログラムを起動するか判断します。起動されるプログラムは行頭の #!
に続くパス名で、例えば catman(1) のように #!/usr/bin/perl となっていれ
ば、/usr/bin/perl が起動されます。
後者は普通のコマンド実行と同じく、shell によってコマンド検索パスを検索
して見つけ出した perl が使われますので、環境変数 $PATH の設定によって
変化する可能性があります。どの perl が使われるか確認するには which(1)
コマンドを利用して以下の様に入力します。
% which perl
/usr/bin/perl (実行結果)
それぞれの perl がどんなバージョンのものか確認するには -v オプション
を使います。*フルパス* で perl を実行して比べてみてください。
たとえば /usr/local/bin にある perl を確認するには
% /usr/local/bin/perl -v
This is perl, version 5.005_03 built for i386-freebsd
... (省略) ...
と入力します。
なお、/usr/bin/perl については FreeBSD 2.2 系列では Version 4、
FreeBSD 3.0-RELEASE 以降では Version 5 になっています。
[管理番号 400] (最終更新 1999/02/17 23:58:45)
Q. FreeBSD で POSIX スレッド (POSIX pThread) は使えますか?
A. はい、使えます。
FreeBSD は IEEE Std 1003.1c-1995 (Threads) に準拠しています。
FreeBSD をインストール後、配布ファイルからシステムマニュアルページ
(man) とソースのシステムライブラリ (lib) をインストールし、man pthread
を実行すると表示される説明を読んでください。
[管理番号 401] (最終更新 2002/03/07 15:32:11)
Q. a.out 形式のシェアドライブラリを作成、利用する例があったら教えてください。
A. 以下に例を説明します。
まず、同じディレクトリに shared.c、test_shared.c を以下の内容で作成
します。
以下は shared.c (共有ライブラリ) の内容です。
----------------- ここから ---------
int
shared(int a)
{
a *= 5;
return(a);
}
----------------- ここまで ---------
以下は test_shared.c (ライブラリを使用する実行ファイル) の内容です。
----------------- ここから ---------
#include <stdio.h>
extern int shared(int);
int
main(void)
{
int a;
printf("number ?:");
scanf("%d", &a);
printf("result: %d\n", shared(a));
return(0);
}
----------------- ここまで ---------
まず、シェアドライブラリを構成するオブジェクトを作成します。オプション
-fpic はシェアドライブラリを構成するオブジェクトを作成するために必要
です。オプション -c はリンクを行わないでソースをコンパイルするために
必要です。
% gcc -fpic -o libshared.SO -c shared.c
次にシェアドライブラリを作成します。
% gcc -shared -Wl,-soname,libshared.so.1 -o libshared.so.1 libshared.SO
そして、ld(1) に見つけてもらうために リンクを張ります。
% ln -s libshared.so.1 libshared.so
最後に、このシェアドライブラリを利用する実行バイナリを作成します。
% gcc -L. -lshared -Wl,-rpath=. -o main test_shared.c
さあ、実行してみましょう。"number ?:" の後に数字を入力してください。こ
こでは 5 を入力しています。
% ./main
number ?:5
result: 25
ダイナミックリンクが本当に行われているか、shared.c を変更し、
libshared.so.1.0 を再作成して、main を実行するとその変更が反映される
ことを確認しましょう。たとえば、shared.c の "a *= 5;" を "a *= 10;" に
変更します。
----参考----
コンパイル時に -fpic を付ける意味
[FreeBSD-tech-jp 2036]
<URL:[BROKEN!] http://hawk.ise.chuo-u.ac.jp/student/person/tshiozak/FreeBSD/shlib1/>
Linux とは違い、FreeBSD では lib${name}.so.X だけ作ればよい。
[FreeBSD-users-jp 60134]
-rpath や $LD_RUN_PATH の $LD_LIBRARY_PATH との違い。
共有ライブラリとのリンクから実行までの過程。
推奨されるライブラリ作成の手順。
[FreeBSD-users-jp 60135]
Executable and Linkable Format (ELF) V1.1
<URL:http://developer.intel.com/vtune/tis.htm>
The Linux Japanese FAQ Project
ELF HOW-TO, GCC HOW-TO など。
<URL:http://www.linux.or.jp/JF/JFdocs/INDEX-programming.html>
[管理番号 509] (最終更新 2000/05/24 21:07:45)
Q. Xlib を用いた C プログラムをコンパイルすると
% cc file.c -lX11
file.c:1: X11/Xlib.h: No such file or directory
file.c:2: X11/Xutil.h: No such file or directory
と、エラーになってしまいます。
A. そのソースコードには
#include <X11/Xlib.h>
#include <X11/Xutil.h>
と書いてあるはずですが、このファイルが見付からなかったということです。
#include 命令で インクルードされるファイルの指定には "" で囲む方法
と <> で囲む方法の2通りがあります。
C コンパイラ (正確にはプリプロセッサ) は
#include "file.h"
と書いてあった場合、インクルードファイルを ソースファイルと同じ
ディレクトリの中から探し、もし見付からなければ次に標準のディレクトリ
から探します。
一方、
#include <file.h>
と書いてあった場合は、ソースファイルと同じディレクトリは探さずに、
最初から標準のディレクトリだけを探します。
通常 標準のディレクトリは、/usr/include/ になっていますので、
/usr/include/X11/Xlib.h や /usr/include/X11/Xutil.h が存在しないため
上記のエラーが発生したのです。
X11/Xlib.h や X11/Xutil.h などの X の include ファイルは
/usr/X11R6/include/ に置いてあるため、この問題を回避するには
コンパイラが /usr/X11R6/include/ を探すようにすればいいわけです。
以下に示す解決策のうち、いずれかを選んで下さい。
1. -I オプションで、インクルードファイルが置いてあるディレクトリを
指定できます。コマンドラインからは、
% cc file.c -I /usr/X11R6/include
などと入力します。この例では、標準のディレクトリである
/usr/include と、-I で指定した /usr/X11R6/include から
インクルードファイルを探します。
ただし、最終的にリンク時にライブラリが見付からないというエラーに
なるでしょうから、
% cc file.c -I /usr/X11R6/include -lX11 -L /usr/X11R6/lib
としなければいけません。→[管理番号 1609]
2. imake/xmkmf (Imakefile というファイルがある場合) や autoconf
(configure というファイルがある場合) などの、Makefile を自動的に
生成するツールを使っているものは、インクルードファイルの検索対象
ディレクトリを指定するためのオプションが用意されていることが
多いです。それぞれのプログラムに付属するドキュメントをよく読んで
みましょう。
[管理番号 587] (最終更新 2003/10/16 23:20:14)
Q. gccで "long double" を使用して数値計算を行ないましたが、同じ CPU での
Linux の結果と比べて計算精度が悪く、計算結果が異なります。
A. FreeBSD の標準カーネルでは浮動小数点の仮数部の精度が (IEEE754 と異なり)
53bit に設定されているために起きる現象です。
long double の仮数部の精度は64bitです。(double の仮数部の精度は 53bit です)
Intel x86 系の FPU の仮数部の精度は 24/53/64bit に設定可能です。
FreeBSD では仮数部の精度が 53bit に設定されているために、long double
を使用しても仮数部の精度が 53bit (つまり、double と同じ) しかありません。
精度を上げて数値計算を行なうには:
1. 関数 fpsetprec()/fpgetprec() を使用して、FPU の仮数部の精度を 64bit
に変更する事が出来ます。fpsetprec(3) を御覧下さい。
2. GNU Multiple Precision Arithmetic Library (GMP)、PARI 等 FreeBSD 標
準以外の数値演算ライブラリを利用してもよいでしょう。
1. fpsetprec()/fpgetprec() について
FreeBSD users MLの以下のメールから始まるスレッドが参考になるでしょう。
Subject: [FreeBSD-users-jp 24352] gcc bug
Subject: [FreeBSD-users-jp 46648] long double
その他、オンラインマニュアル fpsetround(3)、math(3)、ieee(3)などが参考
になります。
ただし、fpsetprec は double の内部演算も 64bit 精度にしてしまうという
副作用があります。double での演算結果が変わってしまう可能性がありますの
で注意して下さい。
long double 使用上の注意点:
* FreeBSD の printf(3) は 5.1-RELEASE から long double に対応しました。
それ以前 (少なくとも 4.8-RELEASE までと、5.0-RELEASE) は、書式で "%Lf"
等を使用してもエラーにはなりませんが、double の精度でしか表示されません。
* long double 用の算術関数 sqrtl(), sinl() 等が標準で用意されていません。
([管理番号 588] 参照)
プログラム例:
----------------------------
#ifdef __FreeBSD__
#include <ieeefp.h>
#endif
...
int main()
{
long double tmp1, tmp2;
...
#ifdef __FreeBSD__
fpsetprec(FP_PE); /* 仮数部の精度を 64bit にする。 */
#endif
...
}
----------------------------
2. 非標準の数値演算ライブラリについて
GMP (ports/math/libgmp4) は、任意多倍長の整数、整数を法とした計算
(modular arithmetic)、有理数、浮動小数点数の四則などが出来ます。但し、
三角関数、対数関数などの初等的な関数もないので、用途が限られるかも知れ
ません (自分で頑張って書けば、勿論問題ないですが)。
PARI (ports/math/pari) は、GMP 同様の数の他、p 進数や、それぞれの数
を係数とした多項式、羃級数、行列やベクトルの計算ができ、初等超越関数
(三角関数や指数対数関数) の他、これでもかというくらい様々な関数が実装
されています。本来は、整数論用のライブラリ集 (と、対話的に計算するため
の gp というコマンド (bc の様な感じ)) で、ちょっとした用途には大げさ
かも知れません。
いずれも C から使うことになるでしょう。(PARIは、Fortran や Pascal から
も使えるようです)。
他に参考になるものとしては
SAL: <URL:http://SAL.linet.gr.jp/index.shtml>
があります。
- [管理番号 587] Q.gccで "long double" を使用して数値計算を行ないましたが、同...
- [管理番号 588] Q.FreeBSD には long double 用の算術関数 sqrtl()、...
- [管理番号 779] Q.i386/i486 を数値演算コプロセッサ (FPU) なしで使用しています...
- [管理番号 787] Q.数値演算コ・プロセッサ (FPU) のない PC で "GPL_MATH_E...
- [管理番号 1541] Q.浮動小数点演算を行なう program が SIGFPE で core du...
[管理番号 588] (最終更新 2000/06/25 02:30:06)
Q. FreeBSD には long double 用の算術関数 sqrtl()、sinl() はないのですか。
A. ありません。しかし、FPU を持っている CPU の場合は、次のような方法が
あります。
一部の算術関数は gcc に最適化フラグ
-O -ffast-math -mfancy-math-387
を付ける事により、builtin function 扱いになり、アセンブラ上に FPU の
命令が直接生成され、使えるようになります。
ただし fmodl() など、使えない算術関数もあります。
どういう関数が使えるかは、gcc の i386.md ファイルを参照して下さい。
(/usr/src/contrib/gcc/config/i386/i386.md)
FreeBSD では long double の算術関数のプロトタイプ宣言が math.h で
行なわれていないので、プログラム中で宣言が必要です。使う関数の
プロトタイプ宣言を Cの参考書等を参考にして追加してください。
FreeBSD の long double は使用上の注意点があります。[管理番号 587]
をご覧ください。
プログラム例
--------------------------------------------------------
#include <stdio.h>
#include <math.h>
#ifdef __FreeBSD__
/* [管理番号 587] を参考ください */
#include <ieeefp.h>
#endif /* __FreeBSD__ */
#ifdef __FreeBSD__
/* プロトタイプ宣言 */
extern long double sinl(long double);
extern long double sqrtl(long double);
#endif /* __FreeBSD__ */
int main()
{
long double ld; double d;
#ifdef __FreeBSD__
/* [管理番号 587] を参考ください */
fpsetprec(FP_PE); /* 仮数部の精度を 64bit にする。 */
#endif /* __FreeBSD__ */
ld = sinl(1.1); d = sin(1.1);
printf("double = %.20f\n", d);
printf("long double = %.20Lf\n", ld);
printf("ld-d = %e\n", (double)(ld-d));
return 0;
}
- [管理番号 587] Q.gccで "long double" を使用して数値計算を行ないましたが、同...
- [管理番号 588] Q.FreeBSD には long double 用の算術関数 sqrtl()、...
- [管理番号 779] Q.i386/i486 を数値演算コプロセッサ (FPU) なしで使用しています...
- [管理番号 787] Q.数値演算コ・プロセッサ (FPU) のない PC で "GPL_MATH_E...
- [管理番号 1541] Q.浮動小数点演算を行なう program が SIGFPE で core du...
[管理番号 627] (最終更新 1999/02/17 23:58:45)
Q. FreeBSDで X (Xlib を使った) のプログラミングをしようと思ったのですが、
コンパイルがうまくいきません。先頭に
#include <X11/Xutil.h>
#include <X11/Xlib.h>
を入れるとうまくコンパイルできないのですが、どうしたらよいでしょうか?
A. コンパイル時に注意することはいくつかあります。
まず最初に Xlib.h Xutil.h をインクルードする際には、Xlib.h → Xutil.h
の順番にインクルードする必要があります。だからソースの先頭は
#include <X11/Xlib.h>
#include <X11/Xutil.h>
と書かなければ失敗します。注意しましょう。
その他 file.c:??: X11/Xlib.h: No such file or directory (?? の部分は
数字) の様なエラーが発生するときは [管理番号 509] を参照してください。
[管理番号 694] (最終更新 1999/02/17 23:58:45)
Q. shellスクリプトなどで、起動したプログラムの戻り値を得るには
どうすればよいのでしょうか?
A. sh系のshellと、csh系のshellとで方法が違います。
sh系 -> $? という変数に戻り値が入っています。
csh系 -> $status という変数に戻り値が入っています。
また、exec ??? でプログラムを起動すると、シェル自身が起動したプログラム
になり、起動したプログラムの戻り値はそのシェルの戻り値になります。
[管理番号 705] (最終更新 1999/02/17 23:58:45)
Q. FreeBSD の kernel の source file を見ていて、次のような記述を見掛け
ました。
#endif NETATALK
#endif の後に、コメントがあるのは良く見ますが、このような記述もあるの
でしょうか?
A. 昔使われていた記述方法です。
info で、cpp -> conditionals -> Conditional Syntax -> #if Directive
とたどっていくと、次のような説明があります。
In fact, you can put anything at all after the `#endif'
and it will be ignored by the GNU C preprocessor,
but only comments are acceptable in ANSI Standard C.
FreeBSD で使われる cc は、GNU C compiler ですので、このような記述がさ
れていても無視されるようです。
GNU C compiler で、option に -ansi -pedantic を付けて compile すると、
ANSI Standard C として動作し warning が出されます。
実際に、option に -ansi -pedantic を付けて compile すると、次のように
warning が出ました。(gcc version 2.7.2.1 にて)
cc -c -O -pipe -Wreturn-type -Wcomment -Wredundant-decls -Wimplicit -Wnested-externs -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Winline -Wuninitialized -ansi -pedantic -nostdinc -I- -I. -I../.. -I../../../include -DKERNEL -include opt_global.h ../../net/if_loop.c
../../net/if_loop.c:83: warning: text following `#endif' violates ANSI standard
../../net/if_loop.c:252: warning: text following `#endif' violates ANSI standard
../../net/if_loop.c:94: warning: ANSI C does not allow extra `;' outside of a function
../../net/if_loop.c: In function `loopattach':
../../net/if_loop.c:119: warning: overflow in implicit constant conversion
[管理番号 841] (最終更新 2001/08/12 02:51:17)
Q. FreeBSD で使える Pascal の処理系はありますか?
A. Pascal のソースを C 言語のソースに変換し、それをさらに C コンパイラで
コンパイルするタイプのものは、p2c と ptoc があります。どちらも
ports/packages に含まれています。sqrt(3) などの libc に含まれない関数を
使う場合は、オプションに -lm を付ける必要があります。→ [管理番号 1609]
また、ネイティブコンパイラ (C 言語に変換しないタイプ) の GNU Pascal
Compiler というものもあります。lang/gpc として port/package が用意されて
います。
[管理番号 1207] (最終更新 1999/04/07 06:23:54)
Q. C言語の printf 文で日本語を表示させようとすると、コンパイル時に
エラーが出るときがあるんですが(コンパイルできる時もある)。
A. ソースの日本語コードが JISコードになっていませんか?
% echo 'あいう' | nkf -j | hexdump -c
0000000 033 $ B $ " $ $ $ & 033 ( B \n
でわかるように、JIS コードの「あ」には " というキャラクタコードが
含まれているため、printf("..") の "" の対応がおかしくなり
コンパイル時にエラーになります。しかし
% echo 'ほげほげ' | nkf -j | hexdump -c
0000000 033 $ B $ [ $ 2 $ [ $ 2 033 ( B \n
のように、JIS コードには常に " が含まれているわけではないので、
表示させたい文字によって、エラーになったりならなかったりします。
EUC だと、日本語部分のコードは ASCII コードとは重ならない値を使うため、
エラーにはなりませんので、ソースを EUC コードに変換してください。
変換方法は
[管理番号 1253]
Q. ファイルの文字コードを変換したいのですが。
[管理番号 1289]
Q. 新規ファイルをエディタで作成したときの、文字コード(JIS、EUCなど)を
指定したいのですが。
を参照してください。
[管理番号 1218] (最終更新 1999/06/03 03:50:53)
Q. package/ports にある、日本語対応の perl (jperl) をインストール
したのですが、日本語に対して split 等を使っても、オリジナルの
perl と同じ挙動になります。
A. jperl (パッケージ名 ja-perl) の日本語機能を使う場合は、
1) スクリプトの先頭行を
#!/usr/local/bin/perl
でなく、
#!/usr/local/bin/jperl
と書く。
2) 日本語を使う前に perl スクリプトに
use I18N::Japanese qw(re);
と書いておく。
のどちらかを行ってください。どちらの条件も満たしていない場合、
jperl はオリジナルの perl として動作します。
また、処理対象の文字列の文字コードを確認してください。→[管理番号 1254]
jperl は、コンパイル時に EUC か SJIS のどちらかを指定してコンパイル
されます。この指定と、処理する文字列の文字コードが合っていないと
正しく処理されません。package/ports の jperl は EUC版になっています。
ただし、-Lsjis オプションをつけると SJIS 版として動きます。
つまり、スクリプトの先頭を
#!/usr/local/bin/jperl
あるいは
#!/usr/local/bin/jperl -Leuc
とすると EUC を扱えますし、
#!/usr/local/bin/jperl -Lsjis
とすれと SJIS を扱うことができます。
[管理番号 1541] (最終更新 2001/10/22 01:18:34)
Q. 浮動小数点演算を行なう program が SIGFPE で core dump してしまいます。
同じ program が他の OS では問題無く動くのに何故でしょうか。
A. 浮動小数例外 (SIGFPE) のデフォルトアクションが「コアイメージの作成」
(core dump) になっている為です。そのため FreeBSD 3.5-RELEASE 以前では、
SIGFPE が発生すると core dump してしまいます。4.0-RELEASE 以降、及び
3.5-STABLE では、標準で SIGFPE が Mask されるようになったので、この
ような問題は起りません。
問題の回避方法について詳しくは
<URL:http://www.jp.FreeBSD.org/ports-jp/tips.html> を御覧下さい。
他にも、オンラインマニュアル fpsetmask(3)、math(3) や
[FreeBSD-ports-jp 1993]
[FreeBSD-users-jp 46652] Re: long double
が参考になるでしょう。
- [管理番号 587] Q.gccで "long double" を使用して数値計算を行ないましたが、同...
- [管理番号 588] Q.FreeBSD には long double 用の算術関数 sqrtl()、...
- [管理番号 779] Q.i386/i486 を数値演算コプロセッサ (FPU) なしで使用しています...
- [管理番号 787] Q.数値演算コ・プロセッサ (FPU) のない PC で "GPL_MATH_E...
- [管理番号 1541] Q.浮動小数点演算を行なう program が SIGFPE で core du...
[管理番号 1609] (最終更新 2000/05/24 21:06:42)
Q. C のソースをコンパイルすると、
... undefined reference to `sin'
... undefined reference to `XOpenDisplay'
などというエラーになります。
A. コンパイルは成功し、オブジェクトファイル (*.o) が生成されましたが、
リンク時に sin・XOpenDisplay という関数が見付からなかったという
エラーです。
/usr/lib/ や /usr/X11R6/lib、/usr/local/lib/ には lib*.so.* や
lib*.a というファイルがあります。これらはライブラリと言い、
コンパイル済の関数群が入っています。
sin は /usr/lib/libm.so.* に、XOpenDisplay は /usr/X11R6/lib/libX11.so.*
に含まれていますので、この場所を教えてやればいいのです。
例えば、sin が見付からないなら
% cc foo.c -lm
とします。XOpenDisplay が見付からないなら
% cc foo.c -lX11 -L /usr/X11R6/lib
とします。
-lm というのは、リンカ (/usr/bin/ld) に
「libm.so.* というライブラリを探しなさい」
というオプションです。
同様に -lX11 というのも
「libX11.so.* というライブラリを探しなさい」
という意味なのですが、ld はデフォルトでは、/usr/lib からしか
ライブラリを探しません。そのため、/usr/X11R6/lib や /usr/local/lib
のライブラリを使う場合は、-L /usr/X11R6/lib などとライブラリの
置いてある場所を指定しなければなりません。
ただし、X のプログラムの場合は、インクルードファイルの場所を指定
しなければいけないので、最終的には、
% cc foo.c -I /usr/X11R6/include -lX11 -L /usr/X11R6/lib
などと -I オプションも指定しなければいけないでしょう。ですから、
Makefile や autoconf などを利用する方が楽です。→[管理番号 509]
なお、どのライブラリにどの関数が含まれているかを調べるには、
まずマニュアルを見ましょう。man sin の SEE ALSO に math(3) と
ありますので、man math を見ると、
These functions constitute the C math library, libm.
とありますので、libm に含まれていることがわかります。
マニュアルから読み取れなかったら、
% nm -o /usr/lib/*.so.* /usr/X11R6/lib/*.so.* | grep ' T sin$'
/usr/lib/libm.so.2:0000b3d8 T sin
% nm -o /usr/lib/*.so.* /usr/X11R6/lib/*.so.* | grep ' T XOpenDisplay$'
/usr/X11R6/lib/libX11.so.6:00020adc T XOpenDisplay
とすればわかります。libm.so.2 なら -lm だし、libX11.so.6 なら
-lX11 ですね。
[管理番号 2228] (最終更新 2004/04/09 05:04:51)
Q. 乱数を得ようと rand(3) を使ったのですが、非常に質の悪い乱数が生成され
てしまいます。
A. FreeBSD の rand 関数は質の悪い乱数生成関数ですので、使わない方がよいで
しょう。
乱数を利用する場合、次の2通りの用途があります。
(1) Monte Carlo 法等のシミュレーション
再現性のある擬似乱数が必要です
(2) 暗号
乱数列が推測できてはいけません
(1) シミュレーション等に用いる擬似乱数
シミュレーション向けの擬似乱数については、2004年現在 Mersenne
Twister が最も良いでしょう。
<URL:http://www.math.keio.ac.jp/~matumoto/mt.html>
詳しくは「間違いだらけの擬似乱数選び」
<URL:http://www.soi.wide.ad.jp/class/20010000/slides/03/>
をご覧ください。
実装については、上記サイトで紹介されているものの他、C++ 版が boost
<URL:http://www.boost.org/>
(ports にもなっています: ports/devel/boost)
に含まれるほか、C# 版が
<URL:http://takel.jp/mt/>
で公開されています。言語によっては処理系や広く使われているライブラリで
提供されていることもあります。
(2) 暗号
暗号に用いる場合、簡単にいうと、生成される乱数列が推測できてはいけません。
FreeBSD では、/dev/random が利用できます。また、RC4 暗号に用いられる疑似
乱数生成関数 arc4random() も用意されています。それぞれ、ramdom(4)、
arc4random(3) のマニュアルを参照してください。
他にも OpenSSL で乱数生成用の API が提供されています (RAND_*)。engine(3)、
rand(3) 等、関連するマニュアルを参照してください。詳しいことは暗号関連の
参考書を調べてください。
なお、OpenSSL のマニュアル rand(3) はシステムの rand(3) 関数と重なって
いるので、man -a 3 rand と -a オプションを指定しないと読めないでしょう。