Bir C programı yazmadan bir sistemdeki veri türlerinin boyutlarını (int, float, double,…) bulmak mümkün mü?


19

Bir C programına yazmadan bir Linux sistemindeki veri türlerinin boyutlarını (int, float, double, ...) bulmak mümkün müdür?

C sonuçları C ++ ile aynı programlama sistemindeki diğer programlama dilleriyle aynı mıdır?


4
Merak ediyorum - bir C programı yazmak istemiyorsanız, C veri türleri diğerinden ziyade bir boyutta ise ne fark eder?
David Cary

7
@DavidCary ABI'leri C dışında bir dilde çağırmak için!
Kaz

Yanıtlar:


18

İstediğiniz veri türünün tanımını biliyorsanız, getconfbu değerleri çoğu Unix sisteminde bulmak için kullanabilirsiniz .

$ getconf CHAR_BIT
8

Değişkenlerin listesi , diskte olmanın man limits.hyanı sıra , man sayfasında da burada tanımlanır man sysconf. Sen kullanabilirsiniz locate limits.hburada sık sık var, onu bulmak için: /usr/include/linux/limits.h.


4
Bunun sadece platformun resmi C derleyicisi için geçerli olduğu uyarısı ile. Resmi derleyicinin farklı boyutlara yol açan alternatif derleyicileri veya alternatif yapılandırmaları (genellikle komut satırı seçenekleri aracılığıyla) olabilir.
Gilles 'SO- kötü olmayı bırak'

@Gilles - Hiç bu değişkenleri listelemenin bir yolunu gördünüz mü? Aradım ve hayatım boyunca bunu yapabilecek bir araç bulamıyorum. Öyle görünüyor. Ayrıca, bu değerleri elde getconfetmenin en güvenli yol olduğu izlenimi altındaydım, söylediğiniz sürece, kutudaki resmi derleyiciyi vuruyorum.
slm

3
Güvenilir bir yol - ve insanların bir C programını derlemek istediklerinde büyük ölçüde kullandıkları bakımda kullandıkları yol, küçük bir C programı derlemektir. Autoconf'un nasıl çalıştığını görün. getconfC derleyicisini (neredeyse) seçeneksiz olarak c89veya çağırmıyorsanız o kadar güvenli değil c99.
Gilles 'SO- kötü olmayı bırak'

11

Türü.

En azından gcc ile bu işe yarar:

$ cpp -dD /dev/null | grep __SIZEOF_LONG__

Neyse, neden bunu yapmak için bir C programı yazmak istemiyorsun? Kabuğunuzdan derleyicinize küçük bir C programı aşağıdaki gibi bir şey gönderebilirsiniz:

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

-x cDildir derleyici söyler Cve -standart girdiden okunan araçları.

Sistemimde, yukarıdaki baskılar:

int=4 bytes
long=8 bytes

Gcc ve clang'da test edilmiştir.


8

Evet. Tarayabilirsin/usr/include/<arch>/limits.h

Örneğin, NetBSD amd64'ümde şunlar /usr/include/amd64/limits.hgösterilir:

#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
Bu genellikle işe yarar, ancak bazen farklı derleyiciler veya derleyici ayarları farklı boyutlara yol açar.
Gilles 'SO- kötü olmayı bırak'

Ben ubuntu sınırlar.h baktığınızda değeri C ön-işlemci tarafından türetiliyor -SHRT_MAX- gibi değişkenlere işaret eder. Bunu nerede bulabilirim?
Bay Doomsbuster

8

Perl yüklüyse bunu perl -V'den alabilirsiniz:

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

Hayır ... olduğunu özellikle 64 bit mimarileri üzerinde temel tiplerinin boyutları farklı fikirlerle ikilileri çalıştırmak mümkün. X86_64'teki en son Linux çekirdekleri yerel 32 bit ikili dosyaları çalıştırabilir ve 32 bit tipli x32 ABI vardır.

Veri türü boyutları, derleyicinin kullandığı boyuttur. Ancak, makinenin verimli bir şekilde desteklediği (1) tiplerin kullanılması ve (2) düşük seviyeli kütüphanelerden kullanıcı uygulamalarına kadar sürekli olarak tiplerin kullanılması avantajlıdır. Birkaç varyantı işlemek sadece bir karışıklıktır.


6

Veri türlerinin boyutları, sistemin değil, bir derleyicinin (veya ABI) bir özelliğidir. Aynı sistemdeki veri türleri için farklı boyutlar kullanan birden fazla derleyiciniz olabilir.


0

Veri türlerine referans veren dizeleri içeren satırları ayrıştırmak ve çıktı almak için bunu deneyin:

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

Bu elbette tanımları yakalar, /usr/include/limits.hböylece bazen artı değerlerle artı daha fazlasını elde edersiniz, ancak çoğunlukla ve komutlarıyla limits.hrahatça bakabileceğiniz şeyleri referans alır .getconf -aulimit -a

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.