เป็นไปได้ที่จะหาขนาดของชนิดข้อมูล (int, float, double, …) ในระบบโดยไม่ต้องเขียนโปรแกรม C หรือไม่?


19

เป็นไปได้ไหมที่จะหาขนาดของชนิดข้อมูล (int, float, double, ... ) บนระบบ Linux โดยไม่ต้องเขียนโปรแกรม C?

ผลลัพธ์สำหรับ C จะเหมือนกับ C ++ และภาษาการเขียนโปรแกรมอื่น ๆ ในระบบ Linux เดียวกันหรือไม่


4
ฉันอยากรู้อยากเห็น - ถ้าคุณไม่ได้ตั้งใจที่จะเขียนโปรแกรม C มันจะแตกต่างกันอย่างไรถ้าประเภทข้อมูล C มีขนาดเดียวมากกว่าที่อื่น
David Cary

7
@DavidCary สำหรับการโทรหา ABI จากภาษาอื่นที่ไม่ใช่ C!
Kaz

คำตอบ:


18

หากคุณทราบคำจำกัดความของชนิดข้อมูลที่คุณต้องการคุณสามารถใช้getconfเพื่อค้นหาค่าเหล่านี้ในระบบ Unix ส่วนใหญ่

$ getconf CHAR_BIT
8

รายการตัวแปรถูกกำหนดไว้ใน man page man limits.hเช่นเดียวกับที่นี่man sysconfนอกเหนือจากการอยู่ในดิสก์ คุณสามารถใช้locate limits.hเพื่อค้นหาได้บ่อยครั้งที่นี่: /usr/include/linux/limits.h.


4
ด้วยข้อแม้ว่าสิ่งนี้ใช้ได้เฉพาะกับคอมไพเลอร์ C อย่างเป็นทางการของแพลตฟอร์ม อาจมีคอมไพเลอร์ทางเลือกหรือการกำหนดค่าทางเลือก (โดยทั่วไปผ่านตัวเลือกบรรทัดคำสั่ง) ของคอมไพเลอร์อย่างเป็นทางการซึ่งนำไปสู่ขนาดที่แตกต่างกัน
Gilles 'หยุดชั่วร้าย'

@Gilles - คุณเคยเห็นวิธีที่จะระบุรายการตัวแปรเหล่านี้จริงหรือไม่? ฉันค้นหามาตลอดและไม่สามารถหาเครื่องมือที่สามารถทำสิ่งนี้ได้ตลอดชีวิต ดูเหมือนว่าจะมี นอกจากนี้ฉันยังรู้สึกว่าการได้รับคุณค่าเหล่านี้getconfเป็นวิธีที่ปลอดภัยที่สุดตราบใดที่คุณพูดว่าฉันกำลังกดปุ่ม "คอมไพเลอร์อย่างเป็นทางการ" ในกล่อง
slm

3
วิธีที่เชื่อถือได้ - และวิธีที่ผู้คนใช้เมื่อพวกเขาใส่ใจซึ่งมีขนาดใหญ่ขึ้นเมื่อพวกเขาต้องการรวบรวมโปรแกรม C - คือการรวบรวมโปรแกรม C ขนาดเล็ก ดูว่า autoconf ทำงานอย่างไร getconfไม่ปลอดภัยดังนั้นถ้าคุณกำลังเรียกคอมไพเลอร์ C เป็นc89หรือc99มี (เกือบ) ไม่มีทางเลือกอื่น
Gilles 'หยุดชั่วร้าย'

11

ชนิดของ

อย่างน้อย gcc จะได้ผลดังนี้:

$ cpp -dD /dev/null | grep __SIZEOF_LONG__

อย่างไรก็ตามทำไมคุณไม่ต้องการเขียนโปรแกรม C เพื่อทำมัน? คุณสามารถส่งโปรแกรม C ตัวจิ๋วไปยังคอมไพเลอร์ของคุณจากเชลล์อย่างนี้:

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 cบอกคอมไพเลอร์ภาษาCและ-วิธีการอ่านจากอินพุตมาตรฐาน

ในระบบของฉันพิมพ์ด้านบน:

int=4 bytes
long=8 bytes

ทดสอบใน gcc และเสียงดังกราว


8

ใช่. คุณสามารถสแกน/usr/include/<arch>/limits.h

ตัวอย่างเช่นใน NetBSD amd64 ของฉัน/usr/include/amd64/limits.hจะแสดง:

#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
วิธีนี้ใช้งานได้ แต่บางครั้งคอมไพเลอร์หรือการตั้งค่าคอมไพเลอร์จะนำไปสู่ขนาดที่แตกต่างกัน
Gilles 'หยุดชั่วร้าย'

เมื่อฉันดูที่ limit.h ใน ubuntu มันจะชี้ไปที่ตัวแปรเช่น -SHRT_MAX- ซึ่งค่าจะได้รับมาจาก C pre-processor ฉันจะหาสิ่งนั้นได้จากที่ไหน
Mr. Doomsbuster

8

หากคุณติดตั้ง Perl คุณสามารถรับได้จาก 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

ไม่ ... เป็นไปได้ที่จะรันไบนารีด้วยแนวคิดที่แตกต่างกันของขนาดของประเภทพื้นฐานโดยเฉพาะในสถาปัตยกรรม 64 บิต เคอร์เนล Linux ล่าสุดบน x86_64 สามารถเรียกใช้ไบนารีเนทีฟแบบ 32 บิตและมีx32 ABI ที่มีชนิด 32 บิต

ขนาดชนิดข้อมูลเป็นส่วนหนึ่งที่คอมไพเลอร์ใช้ แต่จะเห็นได้ชัดว่าเป็นประโยชน์ต่อ (1) ประเภทการใช้งานที่เครื่องรองรับได้อย่างมีประสิทธิภาพและ (2) ประเภทการใช้อย่างสม่ำเสมอจากไลบรารีระดับต่ำผ่านแอปพลิเคชันผู้ใช้ ต้องจัดการกับหลายสายพันธุ์เป็นเพียงความยุ่งเหยิง


6

ขนาดของชนิดข้อมูลเป็นคุณสมบัติของคอมไพเลอร์ (หรือ ABI) ไม่ใช่ของระบบ คุณสามารถมีคอมไพเลอร์หลายตัวโดยใช้ขนาดที่แตกต่างกันสำหรับชนิดข้อมูลในระบบเดียวกัน


0

ลองใช้วิธีนี้ในการแยกวิเคราะห์และส่งออกบรรทัดที่มีสตริงที่อ้างอิงถึงชนิดข้อมูล:

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

แน่นอนว่าคำจำกัดความ/usr/include/limits.hนี้จะทำให้คุณได้รับสิ่งนั้นมากขึ้นบางครั้งก็มีค่า แต่ส่วนใหญ่จะอ้างอิงถึงสิ่งที่ตั้งไว้limits.hซึ่งคุณสามารถดูได้อย่างง่ายดายด้วยคำสั่งgetconf -aและulimit -a

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.