2016-12-14 4 views
17

मैं UEFI ड्राइवर से संबंधित कोड के साथ काम कर रहा था, और मैं इस पार आया:अज्ञात संरचना में पॉइंटर को शून्य पॉइंटर को फिर से परिभाषित करने का उपयोग?

/* EFI headers define EFI_HANDLE as a void pointer, which renders type 
* checking somewhat useless. Work around this bizarre sabotage 
* attempt by redefining EFI_HANDLE as a pointer to an anonymous 
* structure. 
*/ 
#define EFI_HANDLE STUPID_EFI_HANDLE 
#include <ipxe/efi/Uefi/UefiBaseType.h> 
#undef EFI_HANDLE 
typedef struct {} *EFI_HANDLE; 

पूर्ण स्रोत कोड इस पथ http://dox.ipxe.org/include_2ipxe_2efi_2efi_8h_source.html

इस गुमनाम संरचना के साथ मेरी पहली मुठभेड़ है में है, और मैं एक अज्ञात संरचना के लिए एक सूचक को void * को फिर से परिभाषित करने का तर्क नहीं बना सका। "Bizzare sabotage प्रयास" पर एक हैक किस तरह का हैक संकेत देता है?

+1

दिलचस्प विवरण '# परिभाषित' और' # undef' '' include' के आसपास भी है। यह सुझाव देगा कि हेडर 'typedef' के बजाय' # परिभाषित' का उपयोग करता है, जो यह संकेत दे सकता है कि कोड में अन्य डब्ल्यूटीएफ भी हैं। यह टिप्पणी के निष्क्रिय आक्रामक स्वर को समझा सकता है ... – user694733

उत्तर

19

लाइब्रेरी जानकारी का उपयोग कर रही है एक ईएफआई_एचएनडीईएल में दिए गए पते के पीछे आंतरिक डेटा ऑब्जेक्ट पर। लेकिन ऐसा करने में, वे कोड अधिक आकस्मिक बग के लिए अतिसंवेदनशील बना रहे हैं।

सी में, void* पारदर्शी रूप से चेतावनी (यह भाषा डिजाइन द्वारा है) के बिना किसी भी अन्य गैर void* गैर स्थिरांक डेटा सूचक प्रकार लिए डाली है।

गैर-शून्य पॉइंटर प्रकार का उपयोग करके EFI_HANDLE केवल तभी उपयोग किया जाता है जहां EFI_HANDLE संबंधित है। कंपाइलर की टाइप-चेकिंग आपको गले में लाती है जब आप इसे कहीं और पास करते हैं जो EFI_HANDLE नहीं है, बल्कि किसी अन्य चीज़ के लिए पॉइंटर है।

पूर्व: void* के रूप में, यह चेतावनी या त्रुटि

#include <string.h> 

#define EFI_HANDLE void* 

int main() 
{ 
    EFI_HANDLE handle = NULL; 

    strcpy(handle, "Something"); 
} 

बिना संकलित करने के लिए उर्फ ​​बदलने देगा:

typedef struct {} *EFI_HANDLE; 

आगामी "असंगत सूचक प्रकार" काटेंगे संकलन-टाइम त्रुटि।

अंत में, एक गुमनाम struct के रूप में, वहाँ कोई व्यर्थ संरचना टैग पहले से ही-प्रदूषित नाम अंतरिक्ष है कि आप उपयोग कर सकते हैं (गलती से या nefariously) को जोड़ने का नाम है।

+0

यह आपके कंपाइलर सेटिंग्स – StoryTeller

+1

@StoryTeller जावास्क्रिप्ट के आधार पर भी आपको बार-बार लात मार सकता है। http://softwareengineering.stackexchange.com/a/11812/168891 –

+0

मुझे यकीन नहीं है कि मैं सही ढंग से समझता हूं। यदि आप ऐसा करते हैं, तो अब _can_ '* EFI_HANDLE' किस प्रकार इंगित करते हैं? –

7

एक गुमनाम संरचना है, लेकिन एक टैग के बिना एक struct नहीं है यही कारण है कि।

एक अनाम संरचना केवल एक और struct के एक सदस्य,
रूप में रह सकते है और यह भी एक टैग नहीं होना चाहिए।

किसी भी सदस्य के बिना एक struct को परिभाषित अनुमति नहीं है। जो कोड आप देख रहे हैं वह एक कंपाइलर एक्सटेंशन का उपयोग कर रहा है जो इसे अनुमति देता है।

पुस्तकालय इस उपयोगकर्ता से संरचना की परिभाषा को छिपाने के लिए कर रही है, जबकि प्रकार सुरक्षा को बनाए रखने।

लेकिन वहाँ यह करने के लिए एक बेहतर तरीका है।आप एक छिपा संरचना परिभाषा है, तो आप अभी भी यह करने के लिए एक अपारदर्शी सूचक, एक प्रकार है कि परिभाषित कर सकते हैं, तो यह सुरक्षित टाइप है:

struct hidden //defined in a file and not exposed 
{ 
    int a; 
}; 

void Hidden(struct hidden*); 
void Other(struct other*); 
struct hidden* a = NULL; //doesn't see the definition of struct hidden 
Hidden(a); //it may be used 
Other(a); //compiler error 

(से उद्धृत: आईएसओ/आईईसी 98 99: 201x 6.7.2.1 संरचना और संघ विनिर्देशक 13)
एक अज्ञात सदस्य जिसका प्रकार विनिर्देशक कोई टैग विनिर्देशक है जिसे टैग के साथ अज्ञात संरचना कहा जाता है; एक अज्ञात सदस्य जिसका टाइप विनिर्देश के साथ यूनियन विनिर्देशक है, किसी टैग को अनाम संघ कहा जाता है। अज्ञात संरचना या संघ के सदस्यों को युक्त संरचना या संघ के सदस्य माना जाता है। यह को पुनरावर्ती रूप से लागू करता है यदि युक्त संरचना या संघ भी अज्ञात है

+2

उल्लेखनीय मूल्य यह है कि सी मानक के पुराने संस्करणों में, "अज्ञात संरचना" एक अलग अवधि के रूप में मौजूद नहीं थी। उन संस्करणों के लिए, "अज्ञात" का अर्थ केवल "बिना नाम के" सामान्य अंग्रेजी शब्द के रूप में किया जाएगा, जो संरचना प्रकारों के लिए "टैग के बिना" के रूप में व्याख्या करने के लिए बिल्कुल उचित लगता है। – hvd

संबंधित मुद्दे