2008-03-31

int* n; *n = 5; がバスエラーにならない方法

某所の記事内に掲載された表題のコードが話題になっている。
私の手元では必ずバスエラーで死んでしまう。おかしいな。

「そんな、Javaの本に記事を書くような人のコードが間違っているわけがないじゃないですか!」

おお!さすがポジティブシンキング!そうです、きっと私のやりかたが何か間違っているんです。
というわけで、意地でも int *n; *n = 5; を通してみたのがこれ。
(全く同じバージョンのコンパイラじゃないとこの動作にならないので注意)

#include <stdio.h>

int _i;

int main( )
{
int *i;
*(i = &_i+_i) = 1;

/* ここから */
int *n;
*n = 5;

/* ここまで */

printf("%d\n", _i);
return 0;
}

【環境】
gcc --version
i686-apple-darwin9-gcc-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5478)
又は
gcc-4.2 --version
i686-apple-darwin9-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5555)

【コンパイル】
gcc -m64 -O1 hello.c (-m32でも同じだった)

【実行】
./a.out

【結果】
5

【課題】
最適化無し( -O0 ) での動作 - O0だと自動変数の領域が再利用されないみたいなので厳しいかも
他環境への対応 - Linux(x86_64)上の gcc 4.1.2では Segmentation Faultになってしまった。幅広い環境に対応出来る方が良い。

【FAQ】
Q.原理
A.コンパイラに -S をつけてアセンブリ出力させればわかるかも。それで色々試して、「偶然そうなる」方法を探しただけ。

Q.っていうかなんで printfで表示してるのが *nじゃなくて _iなのw
A.代入の時点でバスエラーやSEGVが起こらなければ、そこで*nが 5になることに何ら不思議はなくそれだとつまんないから。

Q.スコープの途中で変数宣言
A.最初は古いCの書法にこだわって書こうと思ったんだけど、今日びのgccじゃ -stdに何を与えてもそれが出来てしまうっぽいのであきらめて使うことにした。

Q._i が初期化されていないんじゃ?
A.そこはゼロクリアされることになってるよ。ISO/IEC 9899:1999>5.1.2 Execution environments>All objects with static storage duration shall be initialized (set totheir initial values) before program startup.


で、真面目な話をすると。
問題のコードがバスエラーにならずに通ってしまうケースがむしろ一番プロジェクトに深刻な打撃を与える。
なにせ「_i には 1を代入したはずなのに、いつのまにか5に置き換わっている」ばかりか、ソースコードをどう追跡したところでポインタ nを用いた間接代入と変数 _iの内容には因果関係など発見できないのだ。

2008-03-27

Gentooで libexpat.so.0が無いと言われた時

error while loading shared libraries: libexpat.so.0: cannot open shared object file: No such file or directory

expatをアップデートしたタイミングで、apacheやらsubversionやらでこんなエラーに遭遇することがある。
libexpatのメジャーバージョンが上がったのに、libexpat.so.0を参照しているバイナリが残っているとこのような問題が起こる。
このようなリンク切れを探し出して再emergeをするには、

revdep-rebuild --library=libexpat.so.0

としてやると良い。ただしrevdep-rebuildコマンドが無い場合は先に emerge gentoolkit すること。

ラベル:

2008-03-21

64bit Gentooで32bitのライブラリが必要になったとき

emul-linux-x86-*シリーズをemergeしてやれば良い

ラベル:

2008-03-19

MySQLにアカウントとデータベースを作成する

ユーザーID: konata
データベース名: konata
パスワード: kagaminmoe

でMySQLのアカウントと専用のデータベースを作成する例(忘れやすいのでメモ)。

rootユーザでMySQLに接続して

create database konata;
grant all privileges on konata.* to konata identified by 'kagaminmoe' with grant option;

2008-03-13

VLANを使っていると、VMWare Fusionでブリッジネットワークを選択したときに vmnet0が無いと言われる

VMWare Fusionの現バージョン(1.1.1)にはバグがあり、どうやら VLANインターフェイスに対して bridged-ethernet用のインターフェイスが作れないらしい。dmesgに下記のようなエラーメッセージが出る。

can't bridge with vlan, bad header length 4.

フォーラムのやりとりを見た感じでは、どうやらバグとして認識しているようなのでいずれ直るかもしれない。

ちなみにVMWare Fusionではブリッジネットワーク用のインターフェイスはデフォルトではテキトーなものが使われる(選択基準わからず)。これを変更するには "/Library/Application Support/VMware Fusion/boot.sh" を編集する。変更はOSの再起動後有効。

2008-03-09

mod_auth_digestがApache2.0と2.2で変わった

Apache2.0の時に使ってたコンフィグを Apache2.2で使おうとしたらこういうことを言われた。
Invalid command 'AuthDigestFile', perhaps misspelled or defined by a module not included in the server configuration

ダイジェスト認証のディレクティブが変わったらしい。

【Apache2.0の時】

AuthUserFile "/etc/apache2/htdigest"

【Apache2.2から】

AuthDigestProvider file
AuthUserFile "/etc/apache2/htdigest"

2008-03-02

Wiresharkで見るためのパケットキャプチャをtcpdumpで取る

tcpdump -i IF名 -s 1500 -w 出力ファイル名

Oracle SQLDeveloperでMySQLを操作する

Oracle社は SQL Developer という Javaベースの GUI DBクライアントを無償で配布している。
普通に考えればそれは Oracle DB専用のツールなのだろうが、実はMySQLや Microsoft SQL Serverへ接続することも出来る。
(Oracle社の立場からすれば、このツールを使ってぜひ Oracle DBへ移行して下さいというのが表向きのところだろう。しかし、そこはそれ)

MySQLをGUIで操作する方法といえば、Microsoft Accessと ODBCドライバを組み合わせて使用するか、Navicatのような商用ソフトウェアか、phpMyAdminのようなWebベースのツールを使うのが一般的であり、よもや Oracle社の無償ツールが使えるなどということを知る人は少ないのではないだろうか。

下記は、SQL DeveloperでMySQLを操作する方法のメモ。

OTN(Oracle Technology Network)から SQL Developer(現在のバージョンは1.2.1)をダウンロード出来る。動作させるにはJRE1.5が必要。
Mac版は 日本のOTNには置いていないようなので、USのOTNからダウンロードすること(但しUIは日本語化されていない)。

SQL Developerには MySQLの JDBCドライバが標準では添付されていないため、展開した SQL Developerの jdbc/libフォルダに mysql-connector-java-*-bin.jarを自分でコピーする。
(Macの場合 SQLDeveloper.app/Contents/Resources/sqldeveloper/jdbc/lib)

SQL Developerを起動し、Tools->Preferences->Database->Third Party JDBC Drivers から先刻コピーした mysql-connector-java-*-bin.jarを追加してやれば、SQL Developerで MySQLへのコネクションを張ることが出来る。

なおUTF-8オンリーの環境でしか動作を確認していないので、他のエンコーディングが関係している場合は文字化けなどを起こすかもしれない。その手の問題に対する対処法についてはここでは取り扱わないので各自で解決されたし。というかUTF-8を使え。

なおMicrosoft SQL Serverへ接続したい場合も JDBCドライバの jarファイル(sqljdbc.jar)を同様にしてセットしてやれば良い。

ラベル: