¿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?
¿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?
Respuestas:
Si conoce la definición del tipo de datos que desea, puede usarla getconf
para 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.h
y aquí, man sysconf
además de estar en el disco. Se puede utilizar locate limits.h
para encontrarlo, es a menudo aquí: /usr/include/linux/limits.h
.
getconf
era la forma más segura, siempre y cuando usted diga, estoy llegando al "compilador oficial" en la caja.
getconf
no es tan seguro, a menos que esté llamando al compilador de C como c89
o c99
con (casi) ninguna opción.
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 c
le 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.
Si. Podrías escanear/usr/include/<arch>/limits.h
Por ejemplo, en mi NetBSD amd64, /usr/include/amd64/limits.h
mostrarí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 */
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
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.
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.h
por lo que obtendrá eso y más, a veces con valores, pero principalmente haciendo referencia a lo que está configurado en el limits.h
que puede ver convenientemente con los comandos getconf -a
y ulimit -a
.