เป็นไปได้ไหมที่จะหาขนาดของชนิดข้อมูล (int, float, double, ... ) บนระบบ Linux โดยไม่ต้องเขียนโปรแกรม C?
ผลลัพธ์สำหรับ C จะเหมือนกับ C ++ และภาษาการเขียนโปรแกรมอื่น ๆ ในระบบ Linux เดียวกันหรือไม่
เป็นไปได้ไหมที่จะหาขนาดของชนิดข้อมูล (int, float, double, ... ) บนระบบ Linux โดยไม่ต้องเขียนโปรแกรม C?
ผลลัพธ์สำหรับ C จะเหมือนกับ C ++ และภาษาการเขียนโปรแกรมอื่น ๆ ในระบบ Linux เดียวกันหรือไม่
คำตอบ:
หากคุณทราบคำจำกัดความของชนิดข้อมูลที่คุณต้องการคุณสามารถใช้getconf
เพื่อค้นหาค่าเหล่านี้ในระบบ Unix ส่วนใหญ่
$ getconf CHAR_BIT
8
รายการตัวแปรถูกกำหนดไว้ใน man page man limits.h
เช่นเดียวกับที่นี่man sysconf
นอกเหนือจากการอยู่ในดิสก์ คุณสามารถใช้locate limits.h
เพื่อค้นหาได้บ่อยครั้งที่นี่: /usr/include/linux/limits.h
.
getconf
เป็นวิธีที่ปลอดภัยที่สุดตราบใดที่คุณพูดว่าฉันกำลังกดปุ่ม "คอมไพเลอร์อย่างเป็นทางการ" ในกล่อง
getconf
ไม่ปลอดภัยดังนั้นถ้าคุณกำลังเรียกคอมไพเลอร์ C เป็นc89
หรือc99
มี (เกือบ) ไม่มีทางเลือกอื่น
ชนิดของ
อย่างน้อย 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 และเสียงดังกราว
ใช่. คุณสามารถสแกน/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 */
หากคุณติดตั้ง 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
ไม่ ... เป็นไปได้ที่จะรันไบนารีด้วยแนวคิดที่แตกต่างกันของขนาดของประเภทพื้นฐานโดยเฉพาะในสถาปัตยกรรม 64 บิต เคอร์เนล Linux ล่าสุดบน x86_64 สามารถเรียกใช้ไบนารีเนทีฟแบบ 32 บิตและมีx32 ABI ที่มีชนิด 32 บิต
ขนาดชนิดข้อมูลเป็นส่วนหนึ่งที่คอมไพเลอร์ใช้ แต่จะเห็นได้ชัดว่าเป็นประโยชน์ต่อ (1) ประเภทการใช้งานที่เครื่องรองรับได้อย่างมีประสิทธิภาพและ (2) ประเภทการใช้อย่างสม่ำเสมอจากไลบรารีระดับต่ำผ่านแอปพลิเคชันผู้ใช้ ต้องจัดการกับหลายสายพันธุ์เป็นเพียงความยุ่งเหยิง
ขนาดของชนิดข้อมูลเป็นคุณสมบัติของคอมไพเลอร์ (หรือ ABI) ไม่ใช่ของระบบ คุณสามารถมีคอมไพเลอร์หลายตัวโดยใช้ขนาดที่แตกต่างกันสำหรับชนิดข้อมูลในระบบเดียวกัน
ลองใช้วิธีนี้ในการแยกวิเคราะห์และส่งออกบรรทัดที่มีสตริงที่อ้างอิงถึงชนิดข้อมูล:
{ 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