È possibile scoprire le dimensioni dei tipi di dati (int, float, double, ...) su un sistema, senza scrivere un programma C?


19

È possibile scoprire le dimensioni dei tipi di dati (int, float, double, ...) su un sistema Linux, senza scrivere un programma C?

I risultati per C sarebbero gli stessi di C ++ e altri linguaggi di programmazione nello stesso sistema Linux?


4
Sono curioso: se non hai intenzione di scrivere un programma C, che differenza fa se i tipi di dati C hanno una dimensione anziché un'altra?
David Cary,

7
@DavidCary Per aver chiamato ABI da una lingua diversa da C!
Kaz,

Risposte:


18

Se conosci la definizione del tipo di dati che desideri, puoi usarli getconfper trovare questi valori sulla maggior parte dei sistemi Unix.

$ getconf CHAR_BIT
8

L'elenco delle variabili è definito nella pagina man limits.hman e anche qui, man sysconfoltre ad essere su disco. Si può usare locate limits.hper trovarlo, è spesso qui: /usr/include/linux/limits.h.


4
Con l'avvertenza che ciò si applica solo al compilatore C ufficiale della piattaforma. Potrebbero esserci compilatori alternativi o configurazioni alternative (in genere tramite le opzioni della riga di comando) del compilatore ufficiale, che portano a dimensioni diverse.
Gilles 'SO- smetti di essere malvagio' il

@Gilles - hai mai visto un modo per elencare queste variabili? Ho cercato e non riesco a trovare nella mia vita uno strumento in grado di farlo. Sembra che ci sarebbe. Inoltre, ho avuto l'impressione che ottenere questi valori getconffosse il modo più sicuro, purché tu dica, sto colpendo "il" compilatore ufficiale sulla scatola.
slm

3
Il modo affidabile - e il modo in cui le persone usano quando si preoccupano, che è generalmente quando vogliono compilare un programma C - è quello di compilare un piccolo programma C. Guarda come funziona autoconf. getconfnon è così sicuro, a meno che tu non stia chiamando il compilatore C come c89o c99con (quasi) nessuna opzione.
Gilles 'SO- smetti di essere malvagio' il

11

Tipo.

Almeno con gcc, funziona:

$ cpp -dD /dev/null | grep __SIZEOF_LONG__

Comunque, perché non vuoi scrivere un programma C per farlo? Puoi inviare un piccolo programma C al tuo compilatore dalla shell in questo modo:

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

La -x cdice al compilatore del linguaggio è C, ed i -mezzi lette dallo standard input.

Sul mio sistema, le stampe sopra:

int=4 bytes
long=8 bytes

Testato in gcc e clang.


8

Sì. Potresti scansionare/usr/include/<arch>/limits.h

Ad esempio, sul mio NetBSD amd64, /usr/include/amd64/limits.hmostrerei:

#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
Questo spesso funziona, ma a volte diverse impostazioni di compilatore o compilatore porteranno a dimensioni diverse.
Gilles 'SO- smetti di essere malvagio' il

Quando guardo i limiti.h in Ubuntu indica variabili come -SHRT_MAX-, il cui valore viene derivato dal pre-processore C. Dove posso trovarlo?
Mr. Doomsbuster,

8

Se hai installato perl puoi ottenerlo da 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

No ... è possibile eseguire binari con idee diverse sulle dimensioni dei tipi di base, in particolare su architetture a 64 bit. I kernel Linux recenti su x86_64 possono eseguire binari nativi a 32 bit e esiste l' ABI x32 con tipi a 32 bit.

Le dimensioni del tipo di dati sono in parte utilizzate dal compilatore. Ma è chiaramente vantaggioso (1) utilizzare tipi che la macchina supporta in modo efficiente e (2) utilizzare tipi in modo coerente dalle librerie di basso livello attraverso le applicazioni utente. Dover gestire diverse varianti è solo un casino.


6

Le dimensioni dei tipi di dati sono di proprietà di un compilatore (o ABI), non del sistema. È possibile avere più compilatori che utilizzano dimensioni diverse per tipi di dati sullo stesso sistema.


0

Prova questo per analizzare e generare le righe contenenti le stringhe che fanno riferimento ai tipi di dati:

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

Questo naturalmente cattura le definizioni in /usr/include/limits.hmodo da ottenere questo e molto altro, a volte con valori, ma soprattutto facendo riferimento a ciò che è impostato in limits.hcui è possibile guardare comodamente con i comandi getconf -ae ulimit -a.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.