¿Es posible averiguar los tamaños de los tipos de datos (int, float, double, ...) en un sistema, sin escribir un programa en C?

19

¿Es posible averiguar los tamaños de los tipos de datos (int, float, double, ...) en un sistema Linux, sin escribir un programa en C?

¿Los resultados para C serán los mismos que para C ++ y otros lenguajes de programación en el mismo sistema Linux?

Tim
fuente
44
Tengo curiosidad: si no tiene la intención de escribir un programa en C, ¿qué diferencia hay si los tipos de datos en C son de un tamaño en lugar de otro?
David Cary
77
@DavidCary ¡Para llamar a ABI desde un lenguaje que no sea C!
Kaz

Respuestas:

18

Si conoce la definición del tipo de datos que desea, puede usarla getconfpara encontrar estos valores en la mayoría de los sistemas Unix.

$ getconf CHAR_BIT
8

La lista de variables se define en la página del manual man limits.hy aquí, man sysconfademás de estar en el disco. Se puede utilizar locate limits.hpara encontrarlo, es a menudo aquí: /usr/include/linux/limits.h.

slm
fuente
44
Con la advertencia de que esto solo se aplica al compilador C oficial de la plataforma. Puede haber compiladores alternativos, o configuraciones alternativas (generalmente a través de opciones de línea de comandos) del compilador oficial, que conducen a diferentes tamaños.
Gilles 'SO- deja de ser malvado'
@Gilles: ¿alguna vez has visto una manera de enumerar estas variables? He estado buscando y no puedo por mi vida encontrar una herramienta que pueda hacer esto. Parece que lo habría. También tenía la impresión de que obtener estos valores getconfera la forma más segura, siempre y cuando usted diga, estoy llegando al "compilador oficial" en la caja.
slm
3
La forma confiable, y la forma en que las personas usan cuando les importa, que es en general cuando quieren compilar un programa en C, es compilar un pequeño programa en C. Vea cómo funciona autoconf. getconfno es tan seguro, a menos que esté llamando al compilador de C como c89o c99con (casi) ninguna opción.
Gilles 'SO- deja de ser malvado'
11

Mas o menos.

Con gcc al menos, esto funciona:

$ cpp -dD /dev/null | grep __SIZEOF_LONG__

De todos modos, ¿por qué no quieres escribir un programa en C para hacerlo? Puede enviar un pequeño programa C a su compilador desde el shell algo como esto:

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

El -x cle dice al compilador que el idioma es C, y los -medios leídos de la entrada estándar.

En mi sistema, lo anterior se imprime:

int=4 bytes
long=8 bytes

Probado en gcc y clang.

Mikel
fuente
8

Si. Podrías escanear/usr/include/<arch>/limits.h

Por ejemplo, en mi NetBSD amd64, /usr/include/amd64/limits.hmostraría:

#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 */
devnull
fuente
44
Esto a menudo funciona, pero a veces diferentes compiladores o configuraciones de compilador conducirán a diferentes tamaños.
Gilles 'SO- deja de ser malvado'
Cuando miro los límites.h en ubuntu, señala variables como -SHRT_MAX-, cuyo valor está derivando el preprocesador de C. ¿Dónde puedo encontrar eso?
Sr. Doomsbuster
8

Si tiene instalado Perl, puede obtenerlo de 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
Mark Wagner
fuente
6

No ... es posible ejecutar binarios con diferentes ideas sobre los tamaños de los tipos básicos, particularmente en arquitecturas de 64 bits. Los núcleos de Linux recientes en x86_64 pueden ejecutar binarios nativos de 32 bits, y existe la ABI x32 con tipos de 32 bits.

Los tamaños de los tipos de datos son en parte los que utiliza el compilador. Pero es claramente ventajoso (1) usar tipos que la máquina admita de manera eficiente y (2) usar tipos consistentemente de las bibliotecas de bajo nivel a través de aplicaciones de usuario. Tener que manejar varias variantes es solo un desastre.

vonbrand
fuente
6

Los tamaños de los tipos de datos son propiedad de un compilador (o ABI), no del sistema. Puede tener múltiples compiladores con diferentes tamaños para tipos de datos en el mismo sistema.

kaalus
fuente
0

Pruebe esto para analizar y generar las líneas que contienen las cadenas que hacen referencia a los tipos de datos:

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

Esto capta, por supuesto, las definiciones, /usr/include/limits.hpor lo que obtendrá eso y más, a veces con valores, pero principalmente haciendo referencia a lo que está configurado en el limits.hque puede ver convenientemente con los comandos getconf -ay ulimit -a.


fuente