是否可以在不编写C程序的情况下找出系统上数据类型的大小(int,float,double,…)?


19

是否可以在Linux系统上找出数据类型的大小(int,float,double,...),而无需编写C程序?

C的结果是否与C ++的结果以及同一Linux系统中的其他编程语言的结果相同?


4
我很好奇-如果您不打算编写C程序,那么C数据类型是一种大小而不是另一种大小有什么不同?
大卫·卡里

7
@DavidCary用于从非C语言调用ABI!
哈兹2014年

Answers:


18

如果您知道数据类型的定义,就可以getconf在大多数Unix系统上使用这些值。

$ getconf CHAR_BIT
8

除了在磁盘上之外,变量列表也在手册页man limits.h以及此处定义man sysconf。您可以使用locate limits.h它来查找它,通常在这里:/usr/include/linux/limits.h


4
需要注意的是,这仅适用于平台的官方C编译器。官方编译器可能存在替代编译器或替代配置(通常通过命令行选项),导致不同的大小。
吉尔(Gilles)'所以

@Gilles-您见过一种将这些变量实际列出的方法吗?我一直在寻找,终生无法找到可以做到这一点的工具。好像会有。同样,我给人的印象是,通过这些值getconf是最安全的方法,只要您说,我就在包装盒上打“官方”编译器。
slm

3
可靠的方法(以及人们在护理时使用的方式,通常是当他们要编译C程序时使用的方式)是编译小型C程序。查看autoconf的工作方式。getconf并不是那么安全,除非您使用C(c89c99几乎没有)选项调用C编译器。
吉尔斯(Gillles)“所以-别再邪恶了”

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
这通常可行,但是有时不同的编译器或编译器设置会导致大小不同。
吉尔斯(Gilles)'“ 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位二进制文​​件,并且x32 ABI具有32位类型。

数据类型大小部分是编译器使用的大小。但是(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.h,您可以使用getconf -aand ulimit -a命令方便地查看它们。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.