É possível descobrir os tamanhos dos tipos de dados (int, float, double, ...) em um sistema, sem escrever um programa em C?


19

É 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?


4
Estou curioso - se você não pretende escrever um programa em C, que diferença faz se os tipos de dados em C são de um tamanho e não de outro?
David Cary

7
@DavidCary Por ligar para ABI de um idioma diferente de C!
Kaz

Respostas:


18

Se você conhece a definição do tipo de dados que deseja, pode getconfencontrar esses valores na maioria dos sistemas Unix.

$ getconf CHAR_BIT
8

A lista de variáveis ​​é definida na página do manual man limits.he aqui, man sysconfalém de estar no disco. Você pode usar locate limits.hpara encontrá-lo, muitas vezes é aqui: /usr/include/linux/limits.h.


4
Com a ressalva de que isso se aplica apenas ao compilador C oficial da plataforma. Pode haver compiladores alternativos ou configurações alternativas (geralmente por meio de opções de linha de comando) do compilador oficial, que levam a tamanhos diferentes.
Gilles 'SO- stop be evil'

@ Gilles - você já viu uma maneira de realmente listar essas variáveis? Estive procurando e não consigo encontrar uma ferramenta que possa fazer isso. Parece que haveria. Também fiquei com a impressão de que obter esses valores getconfera a maneira mais segura, desde que você diga que estou pressionando "o" compilador oficial na caixa.
Slm

3
A maneira confiável - e a maneira como as pessoas usam quando se importam, que geralmente é quando desejam compilar um programa em C - é compilar um pequeno programa em C. Veja como o autoconf opera. getconfnão é tão seguro, a menos que você esteja chamando o compilador C como c89ou c99com (quase) nenhuma opção.
Gilles 'SO- stop be evil'

11

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 cdiz ao compilador que o idioma é Ce 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.


8

Sim. Você pode digitalizar/usr/include/<arch>/limits.h

Por exemplo, no meu NetBSD amd64, /usr/include/amd64/limits.hmostraria:

#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
Isso geralmente funciona, mas às vezes diferentes compiladores ou configurações do compilador levam a tamanhos diferentes.
Gilles 'SO- stop be evil'

Quando olho para o limits.h no ubuntu, ele aponta para variáveis ​​como -SHRT_MAX-, cujo valor está sendo derivado pelo pré-processador C. Onde posso encontrar isso?
Sr. Doomsbuster

8

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

6

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.


6

Tamanhos de tipos de dados são de propriedade de um compilador (ou ABI), não do sistema. Você pode ter vários compiladores usando tamanhos diferentes para tipos de dados no mesmo sistema.


0

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.hpara que você obtenha mais e mais, algumas vezes com valores, mas principalmente fazendo referência ao que está definido no limits.hqual você pode observar convenientemente com os comandos getconf -ae ulimit -a.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.