Можно ли узнать размеры типов данных (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 limits.hтак и здесь, man sysconfпомимо того, что находится на диске. Вы можете использовать , locate limits.hчтобы найти его, он часто здесь: /usr/include/linux/limits.h.


4
С оговоркой, что это относится только к официальному C-компилятору платформы. Могут быть альтернативные компиляторы или альтернативные конфигурации (обычно через параметры командной строки) официального компилятора, которые приводят к различным размерам.
Жиль "ТАК - перестань быть злым"

@ Жиль - ты когда-нибудь видел способ на самом деле перечислить эти переменные? Я искал и не могу на всю жизнь найти инструмент, который может сделать это. Похоже, что будет. Также у меня сложилось впечатление, что получение этих значений getconfбыло самым безопасным способом, так как, как вы говорите, я включаю «официальный» компилятор на коробке.
SLM

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

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
Это часто работает, но иногда разные компиляторы или настройки компилятора приводят к разным размерам.
Жиль "ТАК - перестань быть злым"

Когда я смотрю на limit.h в Ubuntu, он указывает на такие переменные, как -SHRT_MAX-, значение которых выводится препроцессором Си. Где я могу найти это?
Мистер Думсбастер

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.