なんとな~くしあわせ?の日記

「そしてそれゆえ、知識そのものが力である」 (Nam et ipsa scientia potestas est.) 〜 フランシス・ベーコン

C言語のお勉強

comskipをいじっていたらいろいろC言語の課題にぶつかったのでメモ書き
文法とかはどうでもいいんだ、仕様を実装できる仕組みを知りたいのだ。

プリプロセッサで処理分け

#ifdef〜#endifに以下を定義してコードを分岐させる

 _WIN32      … MSW, 32 ビット プラットフォーム
 _WIN64      … MSW, 64 ビット プラットフォーム
 __MINGW32__ … MinGW32
 __MINGW64__ … MinGW64
 __unix__    … Linux, FreeBSD, Mac OSXとか

 同じようなやつで __LINUX__, __FreeBSD__, __APPLE__ とかがあるのでUNIXと判別できた#ifの内部で処理分岐させる場合はそれを使う。

このOSごとに定義されているプリプロセッサシンボル、どっかにまとめないのか。
wxWidgets内部の場合以下にまとめがあるようだ
Preprocessor symbols defined by wxWidgets

FreeBSDはうるさく規定しているみたい
16.6. OS の種類やバージョンの識別

Windows向け関数とUNIXの関数の互換

歴史的経緯は知らないのだけれどSleep()とsleep(), _getcwd(x, y) getcwd(x, y)みたいに名前が微妙に違う関数がいろいろある。手っ取り早いのは#defineで片方の関数を片方の関数で書き換えてしまうことだ。

Sleepは代表的な例だろう、多分これが一番簡単だと思います*1
Cross platform Sleep function for C++ - Stack Overflow

#ifdef _WINDOWS
   #include <windows.h>
#else
   #include <unistd.h>
   #define Sleep(x) usleep((x)*1000)
#endif

MAX_PATH

MAX_PATHという定数値が環境によってばらばららしい。詳しいまとめが以下にあります
MAX_PATH

そもそもMAX_PATHの意味は、Windowsで言えばドライブレターを含んだパスとファイル名全部の長さ?なのだろう。UNIXの場合は_POSIX_PATH_MAXが使えるので、それを使えば良いと思う。

このような定数値は以下のコマンドで確認できる

$ getconf -a | grep PATH_MAX
PATH_MAX                           4096
_POSIX_PATH_MAX                    4096

long long int値を書式文字列で出力

だいたいこの辺が関連ありそう
C の宣言あれこれと printf - satosystemsの日記
long long intが妙 - もぐてっく

clでは以下のコードは通る、gcc(4.7)では警告付きで通る。昔はコンパイルエラーになったのかな?

fprintf(foo, "%lld", bar); // barは long long intを意図

StackOverflowによると、gccで警告なしでコンパイル通すには
c - How to print 64-bit integer in GCC 4.4.1? - Stack Overflow

fprintf(foo, "%I64d", bar); // barは long long intを意図

じゃあなんでそうなるの?という理由まで調べたかったのだけれど、深入りするとまずいっぽいのでやめた。
Why the use of cin,cout or %I64d is preferred over %lld specifier in C++? - Stack Overflow

犬小屋の有効活用

satosystemsさんのところのコードをGCC-4.8にぶち込んでみた、コンパイルエラーになった
[Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ

fpos_t型の大きさを整数型で取得する

fpos_t型は64bitLinuxでは構造体である。
参考:
difference between gcc and vc

サンプルコード

fileendpos.__pos

*1:多分これが一番早いと思います:元ネタ http://dic.nicovideo.jp/id/4996931