Ist es möglich, die Größe von Datentypen (int, float, double, ...) auf einem System herauszufinden, ohne ein C-Programm zu schreiben?


19

Ist es möglich, die Größe von Datentypen (int, float, double, ...) auf einem Linux-System herauszufinden, ohne ein C-Programm zu schreiben?

Würden die Ergebnisse für C dieselben sein wie für C ++ und andere Programmiersprachen in demselben Linux-System?


4
Ich bin gespannt - wenn Sie nicht vorhaben, ein C-Programm zu schreiben, welchen Unterschied macht es dann, wenn C-Datentypen eher eine Größe als eine andere haben?
David Cary

7
@DavidCary Zum Aufrufen von ABIs aus einer anderen Sprache als C!
Kaz

Antworten:


18

Wenn Sie die Definition des gewünschten Datentyps kennen, können Sie getconfdiese Werte auf den meisten Unix-Systemen ermitteln.

$ getconf CHAR_BIT
8

Die Liste der Variablen wird sowohl in der Manpage man limits.hals auch hier definiert und man sysconfbefindet sich nicht nur auf der Festplatte. Sie können verwendet werden, locate limits.hes zu finden, ist es oft hier: /usr/include/linux/limits.h.


4
Mit der Einschränkung, dass dies nur für den offiziellen C-Compiler der Plattform gilt. Möglicherweise gibt es alternative Compiler oder alternative Konfigurationen (normalerweise über Befehlszeilenoptionen) des offiziellen Compilers, die zu unterschiedlichen Größen führen.
Gilles 'SO- hör auf böse zu sein'

@ Gilles - haben Sie jemals einen Weg gesehen, diese Variablen tatsächlich aufzulisten? Ich habe gesucht und kann nicht für das Leben von mir ein Werkzeug finden, das dies tun kann. Scheint so, als würde es so etwas geben. Außerdem hatte ich den Eindruck, dass es getconfam sichersten ist , diese Werte durchzusetzen , solange Sie sagen, dass ich "den" offiziellen Compiler auf der Box getroffen habe.
slm

3
Der verlässliche Weg - und die Art und Weise, wie sich die Menschen darum kümmern, was im Großen und Ganzen der Fall ist, wenn sie ein C-Programm kompilieren möchten - ist das Kompilieren eines kleinen C-Programms. Sehen Sie, wie Autoconf funktioniert. getconfist nicht so sicher, es sei denn, Sie rufen den C-Compiler als c89oder c99mit (fast) keiner Option auf.
Gilles 'SO - hör auf böse zu sein'

11

So'ne Art.

Zumindest mit gcc funktioniert das:

$ cpp -dD /dev/null | grep __SIZEOF_LONG__

Wie auch immer, warum willst du kein C-Programm schreiben, um das zu tun? Sie könnten ein kleines C-Programm aus der Shell an Ihren Compiler senden:

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

Das -x cteilt dem Compiler mit, welche Sprache Cund welches -Mittel von der Standardeingabe gelesen wird.

Auf meinem System wird Folgendes gedruckt:

int=4 bytes
long=8 bytes

Getestet in gcc und clang.


8

Ja. Sie könnten scannen/usr/include/<arch>/limits.h

Auf meinem NetBSD amd64 /usr/include/amd64/limits.hwürde zum Beispiel Folgendes angezeigt :

#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
Dies funktioniert oft, aber manchmal führen unterschiedliche Compiler oder Compilereinstellungen zu unterschiedlichen Größen.
Gilles 'SO- hör auf böse zu sein'

Wenn ich mir die limits.h in Ubuntu ansehe, zeigt sie auf Variablen wie -SHRT_MAX-, deren Wert vom C-Pre-Prozessor abgeleitet wird. Wo finde ich das?
Mr. Doomsbuster

8

Wenn Sie Perl installiert haben, können Sie dies von Perl -V erhalten:

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

Nein ... es ist möglich, Binärdateien mit unterschiedlichen Vorstellungen der Größe von Basistypen auszuführen, insbesondere auf 64-Bit-Architekturen. Neuere Linux-Kernel auf x86_64 können native 32-Bit-Binärdateien ausführen , und es gibt das x32-ABI mit 32-Bit-Typen.

Die Datentypgrößen sind teilweise das, was der Compiler verwendet. Es ist jedoch eindeutig vorteilhaft, (1) Typen zu verwenden, die von der Maschine effizient unterstützt werden, und (2) Typen konsistent aus den Bibliotheken auf niedriger Ebene über Benutzeranwendungen zu verwenden. Es ist nur ein Chaos, mit mehreren Varianten umgehen zu müssen.


6

Datentypgrößen sind eine Eigenschaft eines Compilers (oder ABI), nicht des Systems. Sie können mehrere Compiler mit unterschiedlichen Größen für Datentypen auf demselben System haben.


0

Versuchen Sie dies, um die Zeilen zu analysieren und auszugeben, die die Zeichenfolgen enthalten, die auf die Datentypen verweisen:

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

Dies fängt natürlich die Definitionen in sich auf, /usr/include/limits.hso dass Sie das Plus an mehr erhalten, manchmal mit Werten, aber meistens mit Bezug auf das, was eingestellt ist, in limits.hdem Sie bequem mit den Befehlen getconf -aund nachsehen ulimit -akönnen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.