Kemungkinan untuk mengetahui ukuran tipe data (int, float, double, ...) pada suatu sistem, tanpa menulis program C?


19

Apakah mungkin untuk mengetahui ukuran tipe data (int, float, double, ...) pada sistem Linux, tanpa menulis program C?

Apakah hasil untuk C sama dengan untuk C ++, dan bahasa pemrograman lain dalam sistem Linux yang sama?


4
Saya ingin tahu - jika Anda tidak berniat untuk menulis program C, apa bedanya jika tipe data C satu ukuran daripada yang lain?
David Cary

7
@ DavidCary Untuk memanggil ABI dari bahasa selain C!
Kaz

Jawaban:


18

Jika Anda tahu definisi tipe data yang Anda inginkan, Anda dapat menggunakan getconfuntuk menemukan nilai-nilai ini di sebagian besar sistem Unix.

$ getconf CHAR_BIT
8

Daftar variabel didefinisikan di halaman manual man limits.hdan juga di sini man sysconf, sebagai tambahan pada disk. Anda dapat menggunakan locate limits.huntuk menemukannya, hal ini sering di sini: /usr/include/linux/limits.h.


4
Dengan peringatan bahwa ini hanya berlaku untuk kompiler C resmi platform. Mungkin ada kompiler alternatif, atau konfigurasi alternatif (biasanya melalui opsi baris perintah) dari kompiler resmi, yang mengarah ke ukuran yang berbeda.
Gilles 'SO- stop being evil'

@Gilles - apakah Anda pernah melihat cara untuk benar-benar daftar variabel-variabel ini? Saya sudah mencari dan tidak bisa seumur hidup saya menemukan alat yang bisa melakukan ini. Sepertinya akan ada. Juga saya mendapat kesan bahwa mendapatkan nilai-nilai ini getconfadalah cara yang paling aman, selama Anda mengatakan, saya menekan "the" compiler resmi di kotak.
slm

3
Cara yang dapat diandalkan - dan cara orang menggunakan ketika mereka peduli, yang pada umumnya ketika mereka ingin mengkompilasi program C - adalah mengkompilasi program C kecil. Lihat bagaimana autoconf beroperasi. getconftidak begitu aman, kecuali jika Anda memanggil kompiler C sebagai c89atau c99dengan (hampir) tanpa opsi.
Gilles 'SO- stop being evil'

11

Agak.

Setidaknya dengan gcc, ini berfungsi:

$ cpp -dD /dev/null | grep __SIZEOF_LONG__

Ngomong-ngomong, mengapa Anda tidak ingin menulis program C untuk melakukannya? Anda dapat mengirim program C kecil ke kompiler Anda dari shell sesuatu seperti ini:

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

The -x cmemberitahu compiler bahasa adalah C, dan -sarana membaca dari input standar.

Pada sistem saya, cetakan di atas:

int=4 bytes
long=8 bytes

Diuji dalam gcc dan dentang.


8

Iya. Anda bisa memindai/usr/include/<arch>/limits.h

Sebagai contoh, pada NetBSD amd64 saya, /usr/include/amd64/limits.hakan ditampilkan:

#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
Ini sering berhasil, tetapi terkadang kompiler yang berbeda atau pengaturan kompiler akan mengarah ke ukuran yang berbeda.
Gilles 'SO- stop being evil'

Ketika saya melihat limit.h di ubuntu itu menunjuk pada variabel seperti -SHRT_MAX-, yang nilainya diturunkan oleh prosesor pra-C. Di mana saya dapat menemukan itu?
Tn. Doomsbuster

8

Jika Anda telah memasang perl Anda bisa mendapatkan ini dari 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

Tidak ... itu adalah mungkin untuk menjalankan binari dengan ide-ide yang berbeda dari ukuran tipe dasar, terutama pada arsitektur 64 bit. Kernel Linux terbaru di x86_64 dapat menjalankan binari 32 bit asli, dan ada ABI x32 dengan tipe 32 bit.

Ukuran tipe data sebagian apa yang digunakan kompiler. Tetapi jelas menguntungkan untuk (1) menggunakan jenis yang didukung mesin secara efisien dan (2) menggunakan jenis secara konsisten dari perpustakaan tingkat rendah melalui aplikasi pengguna. Harus menangani beberapa varian hanya berantakan.


6

Ukuran tipe data adalah properti dari kompiler (atau ABI), bukan dari sistem. Anda dapat memiliki beberapa kompiler menggunakan ukuran berbeda untuk tipe data pada sistem yang sama.


0

Coba ini untuk mem-parsing dan menampilkan baris yang berisi string yang merujuk pada tipe data:

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

Ini tentu saja menangkap definisi /usr/include/limits.hsehingga Anda akan mendapatkan itu ditambah lagi, kadang-kadang dengan nilai-nilai, tetapi kebanyakan merujuk pada apa yang diatur di limits.hmana Anda dapat dengan mudah melihat dengan getconf -adan ulimit -aperintah.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.