2009-03-25 18 views
14

私は次のようなことをしようとしています。コードが64ビットマシンでコンパイルされているかどうかを確認するGCCプリプロセッサディレクティブはありますか?

#ifdef 64-bit 
    #define DECIMAL_FORMAT %ld 
#else 
    #define DECIMAL_FORMAT %d 
#endif 
. 
intptr_t d; 
. 
printf(“Some message with DECIMAL_FORMAT in the middle of it\n”, d); 

変数「D」64ビットマシン上で32ビットマシン上のニーズ「%のD」書式指定と形式指定子「%のLD」intptr_t 'タイプである 。私は、GCCのコマンドラインやソースコードを変更せずに、32ビットマシンと64ビットマシンの両方でコードをコンパイルできるようにするためのソリューションを探しています。

答えて

24

私は__LP64__があなたが探しているものかもしれないと思います。 http://gcc.gnu.org/onlinedocs/gcc-4.1.2/cpp/Common-Predefined-Macros.html

ただし、%ldまたは%dの代わりに%p指定子をprintf()に使用することをお勧めします。次に、ポインタのサイズが何であるか心配する必要はありません。

1

アプリケーションをより適切に動作させることをお勧めします。メモリポインタのサイズに依存させる場合、いくつかの望ましくない驚きがあるかもしれません。 Printfはいくつかの型しか理解していませんが、型の値を出力しなければならない場合は、必ずしもそれが実際にわかっているとは限りません。既知の型に変換するほうがはるかに優れています。

printf("Some message with %ld in the middle of it\n", (long) d); 

これは良いアドバイスであり、どのタイプでも有効です。例えば、UnixのPID(つまりはpid_t型である)を印刷する:

pid_t pid = fork(); 
printf("Fork returned %d.\n", (int) pid); 

あなたは限りターゲット・タイプが十分な大きさであるとして、PIDの種類とサイズが何であるかを知っている必要はありません。

+0

私はあなたの一般的な考え方に同意しますが、長いものに合うポインタには依存しないように注意してください。 64ビットWindowsでは、これらのファイルはありません(http://msdn.microsoft.com/en-us/library/s3f49ktz(VS.71).aspx)。ポインタに関しては、 "%p"が正しい方法です(Fred Larsenが指摘したように)。 –

8

あなたはinttypes.hで定義されたPRI*マクロを使用します。これらを有効にするには、__STDC\_FORMAT\_MACROSを定義します。その後、PRIxPTRマクロが__WORDSIZE == 64場合llxに展開し、lxまたはxそうだろう

intptr_t d = ... ; 
printf("This is an intptr_t: %" PRIxPTR "\n", d); 

を使用することができます。

+0

+1本当にクールです。しかし、私のx86-64 Debianシステムの結果は若干異なります。 "echo __WORDSIZE | g ++ -xC++ -include limits.h -P -E - " returns 64. "echo PRIxPTR | g ++ -xC++ -D__STDC_FORMAT_MACROS -include inttypes.h -E - | tail -1"は "l"を返します "バツ"。 – sigjuice

+0

さて、PRI * - マクロはc99なので、マシン上で動作していることを実証できれば、おそらくバグをDebianの人々に報告するはずです。 – JesperE

+0

私の推測は次の通りです: "l" "x"は "lx"です。ポインタと 'long'が両方とも64ビットか両方の32ビットであれば問題ありません。 sizeof(void *)== sizeof(long long) '' sizeof(long long)> sizeof(long) 'の場合にのみポインタを出力するためには" llx "が本当に必要です。 –