एक सिस्टम पर डेटा प्रकार (int, float, double,…) के आकार का पता लगाना संभव है, बिना C प्रोग्राम लिखे?


19

क्या लिनक्स प्रोग्राम पर सी प्रोग्राम लिखे बिना डेटा टाइप्स (int, float, double, ...) के साइज़ का पता लगाना संभव है?

क्या C ++ के समान ही C, और अन्य प्रोग्रामिंग भाषाओं के लिए परिणाम समान Linux सिस्टम में होगा?


4
मैं उत्सुक हूं - यदि आप सी प्रोग्राम लिखने का इरादा नहीं रखते हैं, तो सी डेटा प्रकार एक के बजाय एक आकार के होने से क्या फर्क पड़ता है?
डेविड कैरी

7
@DavidCary सी के अलावा अन्य भाषा से ABI को बुलाने के लिए!
कज़

जवाबों:


18

यदि आप उन डेटा प्रकारों की परिभाषा जानते हैं जो आप चाहते हैं, तो आप getconfइन मूल्यों का पता लगाने के लिए उपयोग कर सकते हैं ।

$ getconf CHAR_BIT
8

चर की सूची को मैन पेज में और डिस्क पर होने के अलावा, man limits.hयहां भी परिभाषित किया गया है man sysconf। आप locate limits.hइसे खोजने के लिए उपयोग कर सकते हैं , यह अक्सर यहां है /usr/include/linux/limits.h:।


4
कैविएट के साथ कि यह केवल प्लेटफॉर्म के आधिकारिक सी कंपाइलर पर लागू होता है। आधिकारिक कंपाइलर के वैकल्पिक कंपाइलर या वैकल्पिक कॉन्फ़िगरेशन (आमतौर पर कमांड लाइन विकल्पों के माध्यम से) हो सकते हैं, जो विभिन्न आकारों को जन्म देते हैं।
गिल्स एसओ- बुराई को रोकना '

@ गिल्स - क्या आपने कभी इन चर को वास्तव में सूचीबद्ध करने का एक तरीका देखा है? मैं देख रहा हूं और मेरे जीवन के लिए ऐसा उपकरण नहीं है जो ऐसा कर सके। लगता है जैसे वहाँ होगा। इसके अलावा, मैं इस धारणा के तहत था कि इन मूल्यों getconfको प्राप्त करना सबसे सुरक्षित तरीका था, इसलिए जब तक आप कहते हैं, मैं बॉक्स पर "आधिकारिक संकलक" मार रहा हूं।
स्लम

3
विश्वसनीय तरीका - और जिस तरह से लोग देखभाल करते हैं, जो कि सी प्रोग्राम को संकलित करना चाहते हैं, जो बड़े और बड़े होते हैं - एक छोटे सी प्रोग्राम को संकलित करना है। देखें कि ऑटोकैफ कैसे संचालित होता है। getconfजब तक आप के रूप में सी संकलक कॉल कर रहे हैं, तो सुरक्षित नहीं है c89या c99(लगभग) कोई विकल्प के साथ।
गिल्स एसओ- बुराई को रोकना

11

एक प्रकार का।

कम से कम gcc के साथ, यह काम करता है:

$ cpp -dD /dev/null | grep __SIZEOF_LONG__

वैसे भी, आप इसे करने के लिए 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 और clang में परीक्षण किया गया।


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
यह अक्सर काम करता है, लेकिन कभी-कभी अलग-अलग संकलक या संकलक सेटिंग्स विभिन्न आकारों को जन्म देंगे।
गिल्स एसओ- बुराई को रोकना '

जब मैं सीमा को देखता हूं। ubuntu में यह -SHRT_MAX- जैसे चर पर इंगित करता है, जिसका मान C प्री-प्रोसेसर द्वारा प्राप्त किया जा रहा है। कहाँ से में इसे प्राप्त कर सकता हूँ?
श्री डूमस्बस्टर

8

यदि आपके पास पर्ल स्थापित है, तो आप इसे 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 बिट आर्किटेक्चर पर के विभिन्न विचारों के साथ बाइनरी चलाना संभव। X86_64 पर हाल के लिनक्स कर्नेल देशी 32 बिट बायनेरिज़ को चला सकते हैं, और 32 बिट प्रकारों के साथ x32 एबीआई है

डेटा प्रकार आकार आंशिक रूप से संकलक का उपयोग करता है। लेकिन यह स्पष्ट रूप से लाभप्रद है (1) उपयोग प्रकार जो मशीन कुशलता से समर्थन करता है और (2) उपयोगकर्ता अनुप्रयोगों के माध्यम से निम्न-स्तरीय पुस्तकालयों से लगातार प्रकार का उपयोग करता है। कई वेरिएंट को हैंडल करना एक गड़बड़ है।


6

डेटा प्रकार के आकार एक संकलक (या एबीआई) की संपत्ति हैं, सिस्टम के नहीं। आप एक ही सिस्टम पर डेटा प्रकारों के लिए विभिन्न आकारों का उपयोग करके कई कंपाइलर रख सकते हैं।


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कमांड के साथ देख सकते हैं ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.