Est-il possible de connaître la taille des types de données (int, float, double,…) sur un système, sans écrire de programme C?


19

Est-il possible de connaître la taille des types de données (int, float, double, ...) sur un système Linux, sans écrire de programme C?

Les résultats pour C seraient-ils les mêmes que pour C ++ et d'autres langages de programmation dans le même système Linux?


4
Je suis curieux - si vous n'avez pas l'intention d'écrire un programme C, quelle différence cela fait-il si les types de données C sont d'une taille plutôt que d'une autre?
David Cary

7
@DavidCary Pour appeler les ABI à partir d'une langue autre que C!
Kaz

Réponses:


18

Si vous connaissez la définition du type de données que vous souhaitez, vous pouvez utiliser getconfpour trouver ces valeurs sur la plupart des systèmes Unix.

$ getconf CHAR_BIT
8

La liste des variables est définie dans la page man limits.hde manuel ainsi qu'ici man sysconf, en plus d'être sur disque. Vous pouvez utiliser locate limits.hpour le trouver, il est souvent ici: /usr/include/linux/limits.h.


4
Avec la mise en garde que cela ne s'applique qu'au compilateur C officiel de la plate-forme. Il peut y avoir des compilateurs alternatifs, ou des configurations alternatives (généralement via des options de ligne de commande) du compilateur officiel, qui conduisent à des tailles différentes.
Gilles 'SO- arrête d'être méchant'

@ Gilles - avez-vous déjà vu un moyen de répertorier ces variables? J'ai cherché et ne peux pas pour la vie de moi trouver un outil qui puisse le faire. On dirait qu'il y en aurait. De plus, j'avais l'impression que faire passer ces valeurs getconfétait le moyen le plus sûr, tant que vous dites, je frappe "le" compilateur officiel sur la boîte.
slm

3
La manière fiable - et la façon dont les gens utilisent quand ils se soucient, ce qui est généralement quand ils veulent compiler un programme C - est de compiler un petit programme C. Découvrez comment fonctionne autoconf. getconfn'est pas si sûr, sauf si vous appelez le compilateur C comme c89ou c99avec (presque) aucune option.
Gilles 'SO- arrête d'être méchant'

11

En quelque sorte.

Avec gcc au moins, cela fonctionne:

$ cpp -dD /dev/null | grep __SIZEOF_LONG__

Quoi qu'il en soit, pourquoi ne voulez-vous pas écrire un programme C pour le faire? Vous pouvez envoyer un petit programme C à votre compilateur à partir du shell quelque chose comme ceci:

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

Le -x cdit au compilateur la langue Cet les -moyens lus à partir de l'entrée standard.

Sur mon système, les impressions ci-dessus:

int=4 bytes
long=8 bytes

Testé en gcc et clang.


8

Oui. Vous pouvez numériser/usr/include/<arch>/limits.h

Par exemple, sur mon NetBSD amd64, /usr/include/amd64/limits.hafficherait:

#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
Cela fonctionne souvent, mais parfois des compilateurs ou des paramètres de compilateur différents conduisent à des tailles différentes.
Gilles 'SO- arrête d'être méchant'

Quand je regarde le limits.h dans ubuntu, il pointe vers des variables comme -SHRT_MAX-, dont la valeur est dérivée par le pré-processeur C. Où puis-je trouver ça?
M. Doomsbuster

8

Si vous avez installé perl, vous pouvez l'obtenir à partir 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

6

Non ... il est possible d'exécuter des binaires avec des idées différentes de la taille des types de base, en particulier sur les architectures 64 bits. Les noyaux Linux récents sur x86_64 peuvent exécuter des binaires 32 bits natifs, et il existe l' ABI x32 avec des types 32 bits.

Les tailles des types de données sont en partie ce que le compilateur utilise. Mais il est clairement avantageux (1) d'utiliser des types que la machine prend en charge efficacement et (2) d'utiliser des types cohérents à partir des bibliothèques de bas niveau via les applications utilisateur. Devoir gérer plusieurs variantes n'est qu'un gâchis.


6

Les tailles des types de données sont la propriété d'un compilateur (ou ABI) et non du système. Vous pouvez avoir plusieurs compilateurs utilisant différentes tailles pour les types de données sur le même système.


0

Essayez ceci pour analyser et sortir les lignes contenant les chaînes référençant les types de données:

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

Cela attrape bien sûr les définitions /usr/include/limits.hafin que vous obteniez cela en plus, parfois avec des valeurs, mais référençant principalement ce qui est défini dans limits.hlequel vous pouvez facilement regarder avec les commandes getconf -aet ulimit -a.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.