Cプログラムを作成せずに、システム上のデータ型(int、float、doubleなど)のサイズを調べることは可能ですか?


19

Cプログラムを作成せずに、Linuxシステムでデータ型のサイズ(int、float、double、...)を調べることは可能ですか?

Cの結果は、C ++の結果と同じLinuxシステムのその他のプログラミング言語と同じですか?


4
私は好奇心が強いです-もしあなたがCプログラムを書くつもりがないなら、Cデータ型が別のサイズではなくあるサイズの場合、それはどのような違いをもたらしますか?
デビッドケアリー

7
@DavidCary C以外の言語からABIを呼び出すため!
カズ

回答:


18

必要なデータ型の定義がわかっている場合は、getconfほとんどのUnixシステムでこれらの値を見つけるために使用できます。

$ getconf CHAR_BIT
8

変数のリストは、ディスク上にあることに加えて、マニュアルページman limits.hとここで定義されていますman sysconf。あなたはlocate limits.hそれを見つけるために使うことができます、それはしばしばここにあります:/usr/include/linux/limits.h


4
これは、プラットフォームの公式Cコンパイラにのみ適用されるという警告があります。公式コンパイラーの代替コンパイラーまたは代替構成(通常はコマンド行オプションを使用)があり、サイズが異なります。
ジル 'SO-悪であるのをやめる'

@Gilles-これらの変数を実際にリストする方法を見たことがありますか?私は探してきましたが、私の人生でこれを行うことができるツールを見つけることはできません。あるようです。また、これらの値を取得するのgetconfが最も安全な方法であるという印象を受けましたが、あなたが言う限り、「公式の」コンパイラーを使用しています。
slm

3
信頼性の高い方法、および人々が気にかけるときに使用する方法は、一般に、Cプログラムをコンパイルするときに使用されますが、小さなCプログラムをコンパイルすることです。autoconfの動作をご覧ください。getconfあなたのようにCコンパイラを呼び出している場合を除き、それほど安全ではないc89か、c99(ほぼ)オプションを指定しないで。
ジル 'SO-悪であるのをやめる'

11

やや。

少なくともgccでは、これは機能します。

$ cpp -dD /dev/null | grep __SIZEOF_LONG__

とにかく、なぜあなたはそれをするCプログラムを書きたくないのですか?シェルから次のような小さなCプログラムをコンパイラに送信できます。

binary=$(mktemp)
cat <<\EOF | cc -o $binary -x c -
#include <stdio.h>
int main() {
    printf("int=%lu bytes\n", sizeof(int));
    printf("long=%lu bytes\n", sizeof(long));
}
EOF
$binary
rm $binary

-x c言語はコンパイラに指示Cし、-手段は、標準入力から読み込みます。

私のシステムでは、上記のように表示されます:

int=4 bytes
long=8 bytes

gccおよびclangでテスト済み。


8

はい。スキャンできた/usr/include/<arch>/limits.h

たとえば、私のNetBSD amd64では、次の/usr/include/amd64/limits.hように表示されます:

#define CHAR_BIT        8               /* number of bits in a char */

#define SCHAR_MAX       0x7f            /* max value for a signed char */
#define SCHAR_MIN       (-0x7f-1)       /* min value for a signed char */

#define UCHAR_MAX       0xff            /* max value for an unsigned char */
#define CHAR_MAX        0x7f            /* max value for a char */
#define CHAR_MIN        (-0x7f-1)       /* min value for a char */

#define USHRT_MAX       0xffff          /* max value for an unsigned short */
#define SHRT_MAX        0x7fff          /* max value for a short */
#define SHRT_MIN        (-0x7fff-1)     /* min value for a short */

#define UINT_MAX        0xffffffffU     /* max value for an unsigned int */
#define INT_MAX         0x7fffffff      /* max value for an int */
#define INT_MIN         (-0x7fffffff-1) /* min value for an int */

#define ULONG_MAX       0xffffffffffffffffUL    /* max value for an unsigned long */
#define LONG_MAX        0x7fffffffffffffffL     /* max value for a long */
#define LONG_MIN        (-0x7fffffffffffffffL-1)        /* min value for a long */

4
これはよく機能しますが、コンパイラまたはコンパイラ設定が異なるとサイズが異なる場合があります。
ジル 'SO-悪であるのをやめる'

私がubuntuのlimits.hを見ると、-SHRT_MAX-のような変数を指していますが、その値はCプリプロセッサによって導出されています。どこで見つけることができますか?
Doomsbuster氏、

8

perlがインストールされている場合、perl -Vからこれを取得できます。

intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
alignbytes=8, prototype=define

6

いや... ある特に64ビットアーキテクチャ上で、基本的な種類の大きさの異なるアイデアをバイナリを実行することが可能に。x86_64上の最近のLinuxカーネルは、ネイティブの32ビットバイナリを実行できます。32ビットタイプのx32 ABIがあります。

データ型のサイズの一部は、コンパイラが使用するものです。ただし、(1)マシンが効率的にサポートする型を使用すること、および(2)ユーザーアプリケーションを通じて低レベルライブラリの型を一貫して使用することは明らかに有利です。いくつかのバリアントを処理しなければならないのは、混乱です。


6

データ型のサイズは、システムではなくコンパイラ(またはABI)のプロパティです。同じシステム上のデータ型に異なるサイズを使用する複数のコンパイラを使用できます。


0

これを試して、データ型を参照する文字列を含む行を解析して出力します。

{ shopt -s globstar; for i in /usr/include/**/*.h; do grep -HE '\b(([UL])|(UL)|())LONG|\bFLOAT|\bDOUBLE|\bINT' $i; done; }

これはもちろん定義をキャッチする/usr/include/limits.hので、値を追加することもありますが、値を使用することもありますが、ほとんどの場合limits.hgetconf -aand ulimit -aコマンドで便利に確認できる設定を参照します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.