É possível descobrir os tamanhos dos tipos de dados (int, float, double, ...) em um sistema Linux, sem escrever um programa C?
Os resultados para C seriam iguais aos de C ++ e outras linguagens de programação no mesmo sistema Linux?
É possível descobrir os tamanhos dos tipos de dados (int, float, double, ...) em um sistema Linux, sem escrever um programa C?
Os resultados para C seriam iguais aos de C ++ e outras linguagens de programação no mesmo sistema Linux?
Respostas:
Se você conhece a definição do tipo de dados que deseja, pode getconf
encontrar esses valores na maioria dos sistemas Unix.
$ getconf CHAR_BIT
8
A lista de variáveis é definida na página do manual man limits.h
e aqui, man sysconf
além de estar no disco. Você pode usar locate limits.h
para encontrá-lo, muitas vezes é aqui: /usr/include/linux/limits.h
.
getconf
era a maneira mais segura, desde que você diga que estou pressionando "o" compilador oficial na caixa.
getconf
não é tão seguro, a menos que você esteja chamando o compilador C como c89
ou c99
com (quase) nenhuma opção.
Mais ou menos.
Com o gcc pelo menos, isso funciona:
$ cpp -dD /dev/null | grep __SIZEOF_LONG__
Enfim, por que você não quer escrever um programa em C para fazer isso? Você pode enviar um pequeno programa C para o seu compilador a partir do shell, algo como isto:
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
O -x c
diz ao compilador que o idioma é C
e os -
meios lidos na entrada padrão.
No meu sistema, as impressões acima:
int=4 bytes
long=8 bytes
Testado em gcc e clang.
Sim. Você pode digitalizar/usr/include/<arch>/limits.h
Por exemplo, no meu NetBSD amd64, /usr/include/amd64/limits.h
mostraria:
#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 */
Se você possui o perl instalado, pode obtê-lo no 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
Não ... é possível executar binários com idéias diferentes dos tamanhos dos tipos básicos, principalmente em arquiteturas de 64 bits. Os kernels recentes do Linux no x86_64 podem executar binários nativos de 32 bits, e há o ABI x32 com tipos de 32 bits.
Os tamanhos dos tipos de dados são parcialmente o que o compilador usa. Mas é claramente vantajoso (1) usar tipos que a máquina suporta eficientemente e (2) usar tipos consistentemente nas bibliotecas de baixo nível por meio de aplicativos do usuário. Ter que lidar com várias variantes é apenas uma bagunça.
Tente isso para analisar e gerar as linhas que contêm as seqüências que referenciam os tipos de dados:
{ shopt -s globstar; for i in /usr/include/**/*.h; do grep -HE '\b(([UL])|(UL)|())LONG|\bFLOAT|\bDOUBLE|\bINT' $i; done; }
Isso captura naturalmente as definições, /usr/include/limits.h
para que você obtenha mais e mais, algumas vezes com valores, mas principalmente fazendo referência ao que está definido no limits.h
qual você pode observar convenientemente com os comandos getconf -a
e ulimit -a
.