Чи можна дізнатися розміри типів даних (int, float, double, ...) в системі, не записуючи програму C?


19

Чи можна дізнатися розміри типів даних (int, float, double, ...) в системі Linux, не записуючи програму C?

Чи будуть результати для C такими ж, як і для C ++, та інших мов програмування в тій же системі Linux?


4
Мені цікаво - якщо ви не збираєтесь писати програму C, яка різниця має значення, якщо типи даних C мають один розмір, а не інший?
Девід Кері

7
@DavidCary Для виклику ABI з іншої мови, ніж C!
Каз

Відповіді:


18

Якщо ви знаєте визначення потрібного типу даних, ви можете використовувати getconfці значення в більшості систем Unix.

$ getconf CHAR_BIT
8

Список змінних визначається як на сторінці man, man limits.hтак і тут man sysconf, на додаток до диска. Ви можете використовувати, locate limits.hщоб знайти його, це часто тут : /usr/include/linux/limits.h.


4
З застереженням, що це стосується лише офіційного компілятора платформи C. Можуть бути альтернативні компілятори або альтернативні конфігурації (як правило, через параметри командного рядка) офіційного компілятора, які призводять до різних розмірів.
Жил "ТАК - перестань бути злим"

@Gilles - ти коли-небудь бачив спосіб перерахувати ці змінні? Я шукав і не можу за все життя знайти інструмент, який би міг це зробити. Здається, було б. Також у мене склалося враження, що отримання цих значень getconfбуло найбезпечнішим способом, доки, як ви кажете, я натискаю на "офіційний компілятор".
slm

3
Надійний спосіб - і спосіб використання людьми, коли вони піклуються, що за великим рахунком, коли вони хочуть скласти програму С - це скласти невелику програму на С. Подивіться, як працює автоконф. getconfне настільки безпечно, якщо ви не викликаєте компілятор C як c89або c99майже (без) жодної опції.
Жил "ТАК - перестань бути злим"

11

Типу.

Щонайменше з gcc, це працює:

$ cpp -dD /dev/null | grep __SIZEOF_LONG__

У будь-якому випадку, чому ви не хочете написати програму 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
Це часто працює, але іноді різні компілятори чи настройки компілятора призводять до різних розмірів.
Жил "ТАК - перестань бути злим"

Коли я дивлюся на limit.h в ubuntu, він вказує на такі змінні, як -SHRT_MAX-, значення яких отримує попередній процесор C. Де я можу це знайти?
Містер Думсбустер

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 - бітних архітектур. Останні ядра Linux на x86_64 можуть запускати власні 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 -aта ulimit -a.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.