2009-08-17 20 views
5

शीर्षक कहता है, क्या यह निर्धारित करने के लिए कोई सुरुचिपूर्ण और सुरक्षित तरीका है कि आर्किटेक्चर 32 बिट या 64 बिट है या नहीं। सुरुचिपूर्ण द्वारा, आप सटीक, सही, संक्षिप्त, साफ और स्मार्ट तरीके से सोच सकते हैं। सुरक्षित रूप से, मानक, सी 8 9/सी 99, और ऑपरेटिंग सिस्टम स्वतंत्रता की अवधि में सुरक्षित सोचें।यह निर्धारित करने के लिए सुरुचिपूर्ण और सुरक्षित तरीका है कि आर्किटेक्चर 32 बिट या 64 बिट

+13

सी में प्रश्न अस्पष्ट है: क्या आप पता लगाने के लिए कि क्या कार्यक्रम का कोड 64-बिट कोड है, या CPU 64-बिट कोड का समर्थन करता है कि क्या (चाहते हैं यानी एक संकलन समय या एक के रूप में रन-टाइम टेस्ट)? –

+6

क्या आप संकलन समय या रनटाइम पर मतलब रखते हैं? कोई विशिष्ट ओएस? –

+1

प्रश्न को 32-बिट या 64-बिट आर्किटेक्चर द्वारा आपके द्वारा परिभाषित किए जाने वाले पहले परिभाषित किए बिना उत्तर नहीं दिया जा सकता है। कोई सार्वभौमिक रूप से स्वीकृत परिभाषा नहीं है। –

उत्तर

3

पॉइंटर्स का आकार वास्तव में परीक्षण करने के लिए एक अच्छी बात नहीं है - मानक सी में बहुत कुछ नहीं है जिसे आप वैसे भी परीक्षण के परिणाम के साथ कर सकते हैं।

मेरे सुझाव परीक्षण ((size_t)-1) है, सबसे बड़ी वस्तु के आकार सी समझता है कि:

if ((size_t)-1 > 0xffffffffUL) 
    { 
      printf("> 32 bits\n"); 
    } 
    else 
    { 
      printf("<= 32 bits\n"); 
    } 

यदि यह एक से अधिक 0xffffffffUL तो आप सिद्धांत रूप में 2**32 - 1 बाइट से बड़ी वस्तुओं हो सकता है, जो की तुलना में एक अधिक सार्थक परीक्षण की तरह लगता है है एक घबराहट "32 बिट्स बनाम 64 बिट्स"।

(उदाहरण के लिए, यदि आप जानते हैं कि size_t का अधिकतम मान केवल 2**32 - 1 है, तो कोई mmap() एक क्षेत्र की तुलना में 1 या 2 जीबी बड़ा करने की कोशिश कर बात है।)

2

सबसे आम तरीका sizeof(void*) और sizeof(int) का परीक्षण करना है (ध्यान दें कि उन्हें जरूरी नहीं होना चाहिए)।

x86/x64 CPUs पर एक और संभावना 'एलएम' ध्वज के लिए परीक्षण करना है। यदि यह मौजूद है तो सीपीयू AMD64 निर्देश सेट को समझता है।

+0

आप सुझाव देते हैं कि दोनों आकारों को ढूंढें और फिर आर्किटेक्चर निर्धारित करें। अन्य सुझाव, 'एलएम' ध्वज के परीक्षण के लिए लगता है कि इसे सी में असेंबलर कोड की आवश्यकता है? – mtasic85

+1

मैंने केवल कोड में विशिष्ट निर्देशों के लिए परीक्षण देखा है (और यह असेंबलर था, हाँ)। हालांकि कई ओएस यूजरलैंड में सीपीयू झंडे का पर्दाफाश करते हैं। उदाहरण के लिए लिनक्स आपको यह जानकारी/proc/cpuinfo में देता है। लेकिन इसके परिणामस्वरूप ओएस आश्रित कोड होगा। – ypnos

+1

क्या होगा यदि आपके पास 64-बिट मशीन पर 32 बिट कंपाइलर संस्करण चल रहा है, तो निश्चित रूप से यह काम नहीं करेगा? – Matt

9

संक्षिप्त उत्तर: कोई

विस्तृत उत्तर: यह बहुत अधिक ओएस/संकलक संयोजन पर निर्भर करता है। उदाहरण के लिए रनटाइम पर, लिनक्स पर आप proc फाइल सिस्टम से पूछ सकते हैं जबकि विंडोज़ पर आप रजिस्टर से पूछ सकते हैं।

आप साबित कर सकते हैं संकलक कि संकलन के लिए इस्तेमाल किया जा रहा एक 32/64 बिट की तरह कुछ का उपयोग करके लक्षित है:

bool is_32bit() { 
    return sizeof(int *) == 4; 
} 

bool is_64bit() { 
    return sizeof(int *) == 8; 
} 

इस सकता है कुछ मान्यताओं के तहत काम करता है (उदाहरण के लिए कार्यावधि में काम करता है)। आप अपने प्लेटफ़ॉर्म के लिए संकलन-समय #define खोज सकते हैं लेकिन यह एक प्रसिद्ध गड़बड़ है।

+0

यदि आप उस पर ऑप्टिमाइज़ेशन चालू करते हैं तो रनटाइम पर मूल्यांकन नहीं किया जाएगा, अनइडेड 32/64 बिट्स कोड हटा दिया जाएगा। इसके अलावा, * बूल * किसी भी सी मानक में नहीं है। – jbcreix

+5

"इसके अलावा, बूल किसी भी सी मानक में नहीं है।" - झूठी, यहमें सी 99 मानक में है - http://en.wikipedia.org/wiki/Stdbool.h –

+0

ओह। बिंदु ले लिया गया, फिर भी, यह सी 8 9 नहीं है जो संभवतः प्रश्न में निर्दिष्ट है क्योंकि सी 99 में इस तरह की अजीब चीज़ों की वजह से। – jbcreix

7

आप जीसीसी उपयोग कर रहे हैं (टैग में संकेत के रूप में) है, तो आप एक संकलन समय परीक्षण

#if __SIZEOF_POINTER__ == 8 

बाहर चाहे वह एक 64-बिट सिस्टम है खोजने के लिए के रूप में, परीक्षण कर सकते हैं। सुनिश्चित करें कि आप जिस जीसीसी संस्करण का उपयोग कर रहे हैं, उसका उपयोग करने से पहले __SIZEOF_POINTER__ को परिभाषित करता है।

+1

यह जीसीसी के लिए संकलन समय पर समस्या हल करता है, और यह अभी तक ठीक है। – mtasic85

+1

+0 डीएफए का जवाब पोर्टेबल है (एक बार जब आप अपने बाहरी बूल प्रकार को हटा दें) और क्लीनर कोड के लिए तैयार करेंगे। फ़ंक्शन हमेशा सत्य या गलत लौटाएगा और संकलक अनियंत्रित कोड को हटा देगा। – jbcreix

2

एक सुरक्षित और पोर्टेबल तकनीक दुर्भाग्य से असंभव है (क्योंकि सुरक्षित और पोर्टेबल केवल आपको सी मानक में नियमों की अनुमति देता है)।

sizeof(int) कुछ सामान्य कंपेलरों के साथ आप 32 बिट प्लेटफ़ॉर्म के लिए 4 और 64 बिट प्लेटफ़ॉर्म के लिए 8 दे सकते हैं लेकिन इसकी गारंटी नहीं है। सभी सी मानक कहते हैं कि एक int लक्ष्य पर गणना के लिए 'प्राकृतिक' आकार होना चाहिए, और इतने सारे कंपाइलर्स ने 64 बिट दुनिया में 4 के रूप में आकार (int) को छोड़ दिया है, इस आधार पर कि यह पर्याप्त है '।

sizeof(void*) बेहतर है क्योंकि संपूर्ण पता स्थान को संबोधित करने के लिए एक सूचक होना उचित आकार होना चाहिए। sizeof(void*) इसलिए आपको उपयुक्त 4 या 8 देने की संभावना है। तकनीकी रूप से, यहां तक ​​कि यह आकार के रूप में भी गारंटी नहीं है, आपको कुछ स्टोर करने के लिए आवश्यक बाइट्स की संख्या देता है, और बाइट को 8 बिट्स नहीं होने चाहिए। एक बाइट तकनीकी रूप से स्मृति की सबसे छोटी एड्रेसेबल यूनिट है जो अधिकांश प्लेटफार्मों पर 8 बिट्स होती है जो लोगों का उपयोग किया जाता है। 8 बिट एड्रेसेबल बहुत आम है, लेकिन मैं चिप्स के साथ काम करता हूं जो 16 बिट एड्रेस करने योग्य और 16 बिट शब्द आकार (इसलिए sizeof(int) 1 है)। तो, यदि आपका बाइट आकार 8 बिट नहीं है, तो sizeof(void*) आपको विभिन्न प्रकार के मूल्य दे सकता है।

दूसरी तरफ, यदि आप केवल x86 और x64 (32 बिट और 64 बिट पीसी प्रोसेसर) के बीच अंतर करने की कोशिश कर रहे हैं तो आकार (शून्य *) पर्याप्त होगा, और कंपेलरों में पोर्टेबल होगा।

+1

आप बिट्स में अपने आकार को खोजने के लिए CHAR_BIT द्वारा आकार (शून्य *) गुणा कर सकते हैं (हालांकि मानक मानक गारंटी नहीं देता है कि प्रतिनिधित्व में सभी बिट्स मूल्य बिट्स हैं - असल में वर्तमान x86_64 कार्यान्वयन में आमतौर पर क्षेत्र में कहीं भी है वर्चुअल एड्रेस में 48 वैल्यू बिट्स का)। – caf

1

कोड बैंक पर 32-बिट या डेटा बैंक पर 32-बिट। :-) 8086 प्रोसेसर में 20-बिट कोड मेमोरी वाला 16-बिट डेटा था। इसके अलावा, आधुनिक हावर्ड मशीन कोड/डेटा अलगाव के साथ अजीब चीजें करते हैं ...

आप x86 प्रोसेसर के लिए cpuid निर्देश देख सकते हैं। अन्य प्रोसेसर परिवारों के पास ऐसा निर्देश नहीं हो सकता है ... वाईएमएमवी।

1
int iedx; 

__asm 
{ 

mov eax, 0x80000001; 
cpuid; 
mov, iedx,edx; 
} 

    if (iedx & (1 << 29)) 
     { 
     return 1; 
     } 
    return 0; 
+0

अधिकांश समय में कंप्यूटर आर्किटेक्चर x86 और x86_64 को नहीं, बल्कि जेनेरिक आर्किटेक्चर के लिए संदर्भित करता है। यह कोड मानक नहीं है और पोर्टेबल नहीं है। – osgx