2012-06-01 16 views
5

मैं थोड़ा-क्षेत्र (पूरी तरह से 32 बिट चौड़ाई) के साथ एक struct है और मैं एक 32-बिट चर है।बिट-फ़ील्ड वाले स्ट्रक्चर को मान कैसे असाइन करें?

error: conversion from ‘uint32_t {aka unsigned int}’ to non-scalar type ‘main()::CPUID’ requested.

struct CPUIDregs 
    { 
     uint32_t EAXBuf; 
    }; 
CPUIDregs CPUIDregsoutput; 


int main() { 

struct CPUID   
    { 
      uint32_t Stepping   : 4;   
      uint32_t Model   : 4;   
      uint32_t FamilyID   : 4;   
      uint32_t Type    : 2;   
      uint32_t Reserved1  : 2;   
      uint32_t ExtendedModel : 4;   
      uint32_t ExtendedFamilyID : 8;   
      uint32_t Reserved2  : 4;   
    }; 

    CPUID CPUIDoutput = CPUIDregsoutput.EAXBuf; 

आप कैसे सबसे छोटा रास्ता में यह करने के लिए किसी भी विचार है: जब मैं अपने struct चर मान असाइन करने का प्रयास करें, मैं एक त्रुटि मिल गया? धन्यवाद

पी.एस. बेशक मेरे पास असली कोड में ईएक्स का अधिक उचित मूल्य है, लेकिन मुझे लगता है कि यह यहां प्रभावित नहीं होता है।

+3

आप यहां 'संरचना' की बजाय 'संघ' चाहते हैं। अन्यथा आप केवल प्रत्येक चर को संरचना में अलग-अलग सेट कर सकते हैं। आप 'ऐसा नहीं कर सकते CPUID CPUIDoutput = EAX, यह अधिक स्पष्ट रूप से कारण है कि मैं एक ही बार में पूरी संरचना करने के लिए EAX आवंटित करने के लिए कोशिश कर रहा हूँ' – andre

उत्तर

7

आप कैसे संकलक स्मृति में अपनी संरचना बाहर देता है पर भरोसा नहीं किया जाना चाहिए। एक ही असाइनमेंट के साथ आप जो चाहते हैं उसे करने के तरीके हैं, लेकिन मैं न तो आपको सलाह दूंगा और न ही आपको बताऊंगा।

काम करने के लिए किया जाएगा निम्नलिखित सबसे अच्छा तरीका है:

static inline void to_id(struct CPUid *id, uint32_t value) 
{ 
    id->Stepping   = value & 0xf; 
    id->Model   = (value & (0xf << 4)) >> 4; 
    id->FamilyID   = (value & (0xf << 8)) >> 8; 
    id->Type    = (value & (0x3 << 12)) >> 12; 
    id->Reserved1  = (value & (0x3 << 14)) >> 14; 
    id->ExtendedModel = (value & (0xf << 16)) >> 16; 
    id->ExtendedFamilyID = (value & (0xff << 20)) >> 20; 
    id->Reserved2  = (value & (0xf << 28)) >> 28; 
} 

और विपरीत

static inline uint32_t from_id(struct CPUid *id) 
{ 
    return id->Stepping 
     + ((uint32_t)id->Model << 4) 
     + ((uint32_t)id->FamilyID << 8) 
     + ((uint32_t)id->Type << 12) 
     + ((uint32_t)id->Reserved1 << 14) 
     + ((uint32_t)id->ExtendedModel << 16) 
     + ((uint32_t)id->ExtendedFamilyID << 20) 
     + ((uint32_t)id->Reserved2 << 28); 
} 
+0

अब, मैं केवल मेरे लिए असाइनमेंट का तरीका देखता हूं। – Irina

+0

@ उपयोगकर्ता 1430759। ऐसा करने का यह एकमात्र सुरक्षित/पोर्टेबल तरीका है। प्रदर्शन के बारे में चिंता न करें क्योंकि यह संकलक द्वारा अनुकूलित सभी को बहुत अधिक प्राप्त करेगा। साथ ही, कोड चिपकाने से पहले संख्याओं को दोबारा जांचने का प्रयास करें। – Shahbaz

+0

और अगर आपको जवाब पसंद आया तो उसे अप-वोट करने और स्वीकार करने के लिए स्वतंत्र महसूस करें;) – Shahbaz

1

ये संरचना सदस्य हैं, इसलिए आपको सीधे उन्हें असाइन करने की आवश्यकता है, या सुनिश्चित करें कि आपके असाइनमेंट का आरएचएस CPUID प्रकार का मान है। सुनिश्चित नहीं है कि आप एक पूर्णांक से संरचना को असाइन करने में सक्षम होने की अपेक्षा क्यों करते हैं।

तथ्यों कि struct bitfields शामिल है, और है कि बिट्स की राशि पूर्णांक में बिट्स आप आवंटित करने के लिए कोशिश कर रहे हैं की संख्या के रूप में ही होता है, कुछ भी नहीं मतलब है। असाइनमेंट उद्देश्यों के लिए वे अभी भी संगत प्रकार नहीं हैं।

यदि यह बहुत अस्पष्ट था, अधिक/बेहतर कोड दिखाने पर विचार करें।

+0

मैं संपादित कोड संस्करण में लगता है, '' तुम क्या करने CPUIDoutput.stepping = EAX होगा। तो, वैसे भी अगर मैं आपको सही समझता हूं, तो मेरे लिए ऐसा करने का कोई तरीका नहीं है? मैं केवल प्रत्येक फ़ील्ड को अलग से असाइन कर सकता हूं? – Irina

2

बस अगर somebody's रुचि, मैं एक बेहतर समाधान मेरे अपने के लिए मिला प्रश्न:

*(reinterpret_cast<uint32_t *> (&CPUIDoutput)) = CPUIDregsoutput.EAXBuf; 
+1

यह मेरे संघ के सुझाव से भी बदतर है। –

+1

@ अन्ना, मुझे आशा है कि आप इसे वास्तविक कोड में उपयोग नहीं कर रहे हैं जिसका उपयोग वास्तविक परिस्थितियों में किया जाएगा। समस्या यह है कि संकलक अनुकूलन उद्देश्यों के लिए आपकी संरचना के सदस्यों के बीच पैडिंग जोड़ने के लिए स्वतंत्र है। तो, आप एक ही लेआउट रखने के लिए अपनी संरचना और अपने नंबर पर भरोसा नहीं कर सकते हैं। पैडिंग के बिना भी, आपका कथन पूरी तरह से एक बड़ी-अंत मशीन में गलत होगा। – Shahbaz

3

संघ का उपयोग करें।

union foo { 
    struct { 
     uint8_t a : 4; 
     uint8_t b : 4; 
     uint8_t c : 4; 
     uint8_t d : 4; 
     uint16_t e; 
    }; 
    uint32_t allfields; 
}; 

int main(void) { 
    union foo a; 

    a.allfields = 0; 
    a.b = 3; 

    return 0; 
}