यदि मैं C / C ++ में 0-आकार के सरणी को परिभाषित करता हूं तो क्या होगा?


127

बस जिज्ञासु, अगर मैं int array[0];कोड में शून्य-लंबाई सरणी को परिभाषित करता हूं तो वास्तव में क्या होता है ? जीसीसी बिल्कुल शिकायत नहीं करता है।

नमूना कार्यक्रम

#include <stdio.h>

int main() {
    int arr[0];
    return 0;
}

स्पष्टीकरण

मैं वास्तव में यह पता लगाने की कोशिश कर रहा हूं कि क्या शून्य-लंबाई सरणियों ने इस तरह से इनिशियलाइज़ किया है, बजाय इसके कि डार्ज़र की टिप्पणियों में परिवर्तनीय लंबाई की तरह इंगित किया जाए, अनुकूलित किया गया है या नहीं।

ऐसा इसलिए है क्योंकि मुझे कुछ कोड को जंगल में छोड़ना है, इसलिए मैं यह पता लगाने की कोशिश कर रहा हूं कि क्या मुझे उन मामलों को संभालना है जहां SIZEइसे परिभाषित किया गया है 0, जो कुछ कोड में एक सांख्यिकीय रूप से परिभाषित है।int array[SIZE];

मुझे वास्तव में आश्चर्य हुआ कि जीसीसी शिकायत नहीं करता है, जिसके कारण मेरा सवाल बन गया। मेरे द्वारा प्राप्त किए गए उत्तरों से, मेरा मानना ​​है कि चेतावनी की कमी पुराने कोड का समर्थन करने के कारण है, जो नए [] सिंटैक्स के साथ अद्यतन नहीं किया गया है।

क्योंकि मैं मुख्य रूप से त्रुटि के बारे में सोच रहा था, मैं लुंडिन के उत्तर को सही मान रहा हूं (नवाज पहले थे, लेकिन यह पूर्ण नहीं था) - अन्य लोग पूंछ-गद्देदार संरचनाओं के लिए इसके वास्तविक उपयोग की ओर इशारा कर रहे थे, जबकि प्रासंगिक, isn ' टी बिल्कुल वही जो मैं ढूंढ रहा था।


51
@AlexanderCorwin: दुर्भाग्य से C ++ में, अपरिभाषित व्यवहार, गैर-मानक एक्सटेंशन, और अन्य विसंगतियों के साथ, खुद को बाहर करने की कोशिश करना अक्सर ज्ञान का मार्ग नहीं होता है।
बेंजामिन लिंडले

5
@JustinKirk मैं बस परीक्षण और इसे काम करके जब्त करके फंस गया। और मुझे अपने पोस्ट में प्राप्त आलोचना के कारण, मैंने सीखा कि परीक्षण और इसे काम करने के लिए जब्त करने का मतलब यह नहीं है कि यह वैध और कानूनी है। तो एक आत्म परीक्षण कभी-कभी मान्य नहीं होता है।
स्टॉर्मबाइट

2
@JustinKirk, एक उदाहरण के लिए मैथ्यू का जवाब देखें कि आप इसका उपयोग कहां करेंगे। यह एक टेम्पलेट में भी काम आ सकता है जहाँ सरणी आकार एक टेम्पलेट पैरामीटर है। प्रश्न में उदाहरण स्पष्ट रूप से संदर्भ से बाहर है।
मार्क रैनसम

2
@JustinKirk: []पायथन या ""सी में भी क्या उद्देश्य है? कभी-कभी, आपको एक फ़ंक्शन या मैक्रो मिला है जिसमें एक सरणी की आवश्यकता होती है, लेकिन आपके पास इसमें डालने के लिए कोई डेटा नहीं है।
dan04

15
"C / C ++" क्या है? ये दो अलग-अलग भाषाएं हैं
को ऑर्बिट

जवाबों:


86

एक सरणी में शून्य आकार नहीं हो सकता।

आईएसओ 9899: 2011 6.7.6.2:

यदि अभिव्यक्ति एक स्थिर अभिव्यक्ति है, तो इसका मूल्य शून्य से अधिक होगा।

उपरोक्त पाठ एक सादा सरणी (पैराग्राफ 1) के लिए दोनों सत्य है। VLA (वेरिएबल लेंथ एरे) के लिए, अभिव्यक्ति का मान शून्य (पैराग्राफ) के बराबर या उससे कम होने पर व्यवहार अपरिभाषित होता है। यह सी मानक में मानक पाठ है। एक कंपाइलर को इसे अलग तरीके से लागू करने की अनुमति नहीं है।

gcc -std=c99 -pedantic गैर-वीएलए मामले के लिए चेतावनी देता है।


34
"यह वास्तव में एक त्रुटि देना चाहिए" - "चेतावनियों" और "त्रुटियों" के बीच का अंतर मानक में मान्यता प्राप्त नहीं है (यह केवल "निदान" का उल्लेख करता है), और एकमात्र स्थिति जहां संकलन को रोकना चाहिए [अर्थात वास्तविक दुनिया अंतर चेतावनी और त्रुटि के बीच] एक #errorनिर्देश का सामना करने पर है ।
रैंडम 832

12
FYI करें, एक सामान्य नियम के रूप में, (C या C ++) मानकों में केवल यह बताया गया है कि कंपाइलरों को क्या अनुमति देनी चाहिए , लेकिन वे नहीं जो उन्हें अस्वीकार करना चाहिए । कुछ मामलों में, वे बताएंगे कि संकलक को "निदान" जारी करना चाहिए, लेकिन यह उतना ही विशिष्ट है जितना कि वे प्राप्त करते हैं। बाकी को कंपाइलर वेंडर के पास छोड़ दिया जाता है। EDIT: क्या Random832 ने भी कहा।
mcmcc

8
@Lundin "एक संकलक को बाइनरी बनाने की अनुमति नहीं है जिसमें शून्य-लंबाई सरणियाँ हैं।" मानक का कहना बिल्कुल ऐसा कुछ नहीं। यह केवल यह कहता है कि इसके कोड को कम से कम एक डायग्नोस्टिक संदेश उत्पन्न करना चाहिए जब इसके आकार के लिए शून्य-लंबाई स्थिर अभिव्यक्ति के साथ एक सरणी वाला स्रोत कोड दिया गया हो। एकमात्र परिस्थिति जिसके तहत मानक एक बाइनरी बनाने के लिए एक संकलक को मना करता है, अगर यह एक #errorप्रीप्रोसेसर निर्देश का सामना करता है ।
रैंडम 832

5
@ लुंडिन सभी सही मामलों के लिए एक बाइनरी उत्पन्न करना # 1 को संतुष्ट करता है, और गलत मामलों के लिए किसी को उत्पन्न करना या उत्पन्न नहीं करना इसे प्रभावित नहीं करेगा। # 3 के लिए एक चेतावनी प्रिंट करना पर्याप्त है। इस व्यवहार की # 2 से कोई प्रासंगिकता नहीं है, क्योंकि मानक इस स्रोत कोड के व्यवहार को परिभाषित नहीं करता है।
रैंडम 832

13
@ लुंडिन: मुद्दा यह है कि आपका कथन गलत है; जब तक एक डायग्नोस्टिक जारी किया जाता है, तब अनुरूप संकलक को एक द्वि-लंबाई सरणियों वाले द्विआधारी के निर्माण की अनुमति होती है।
कीथ थॉम्पसन

85

मानक के अनुसार, इसकी अनुमति नहीं है।

हालांकि यह सी संकलकों में वर्तमान घोषणाओं को एक लचीली सरणी सदस्य ( FAM ) घोषणा के रूप में व्यवहार करने के लिए किया गया है :

C99 6.7.2.1, ,16 : एक विशेष मामले के रूप में, एक से अधिक नामित सदस्य के साथ संरचना का अंतिम तत्व एक अपूर्ण सरणी प्रकार हो सकता है; इसे एक लचीली सरणी सदस्य कहा जाता है।

FAM का मानक सिंटैक्स है:

struct Array {
  size_t size;
  int content[];
};

विचार यह है कि आप इसे फिर से आवंटित करेंगे:

void foo(size_t x) {
  Array* array = malloc(sizeof(size_t) + x * sizeof(int));

  array->size = x;
  for (size_t i = 0; i != x; ++i) {
    array->content[i] = 0;
  }
}

आप इसे सांख्यिकीय रूप से भी उपयोग कर सकते हैं (जीसीसी एक्सटेंशन):

Array a = { 3, { 1, 2, 3 } };

यह पूंछ-गद्देदार संरचनाओं के रूप में भी जाना जाता है (यह शब्द C99 मानक के प्रकाशन से पहले) या संरचना हैक (इसे इंगित करने के लिए जो रेसेनिग के लिए धन्यवाद)।

हालाँकि यह सिंटैक्स मानकीकृत था (और गारंटी वाले प्रभाव) केवल C99 में हाल ही में। इससे पहले एक निरंतर आकार आवश्यक था।

  • 1 जाने का पोर्टेबल तरीका था, हालांकि यह अजीब था।
  • 0 इरादे को इंगित करने में बेहतर था, लेकिन कानूनी रूप से नहीं, जहां तक ​​मानक का संबंध था और कुछ संकलक (gcc सहित) द्वारा विस्तार के रूप में समर्थित था।

हालांकि, टेल पैडिंग प्रथा इस तथ्य पर निर्भर करती है कि भंडारण उपलब्ध है (सावधान malloc) इसलिए सामान्य रूप से स्टैक उपयोग के लिए अनुकूल नहीं है


@ लुंडिन: मैंने यहां कोई वीएलए नहीं देखा है, सभी आकार संकलन समय पर जाने जाते हैं। लचीला सरणी अवधि से आता है gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Zero-Length.html और हरिणी अर्हता int content[];जहाँ तक मैं समझता हूँ कि यहाँ। चूँकि मैं कला की सी शर्तों पर बहुत ज्यादा जानकार नहीं हूँ ... क्या आप इस बात की पुष्टि कर सकते हैं कि क्या मेरा तर्क सही है?
मैथ्यू एम।

@ मैथ्यूएमएम .: C99 6.7.2.1, As16: एक विशेष मामले के रूप में, एक से अधिक नामित सदस्य के साथ संरचना का अंतिम तत्व एक अपूर्ण सरणी प्रकार हो सकता है; इसे एक लचीली सरणी सदस्य कहा जाता है।
क्रिस्टोफ

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

1
संरचना हैक के लिए 1 के एक सरणी आकार का उपयोग करने से कंपाइलर स्क्वॉक होने से बच जाएगा, लेकिन केवल "पोर्टेबल" था क्योंकि कंपाइलर लेखक इस तरह के उपयोग को डी-फैक्टो मानक के रूप में स्वीकार करने के लिए पर्याप्त थे। क्या यह शून्य-आकार के सरणियों पर प्रतिबंध के लिए नहीं था, प्रोग्रामर ने एक तत्व विकल्प के रूप में एकल-तत्व सरणियों के परिणामी उपयोग, और संकलक लेखकों के ऐतिहासिक रवैये को बताया कि मानक, संकलक लेखकों द्वारा आवश्यक नहीं होने पर भी उन्हें प्रोग्रामर की जरूरतों की सेवा करनी चाहिए। जब भी एकल-तत्व सरणी को आसानी से और उपयोगी रूप से अनुकूलित foo[x]किया गया। foo[0]foo
सुपरकैट

1
@RobertSsupportsMonicaCellio: यह उत्तर में स्पष्ट रूप से दिखाया गया है, लेकिन अंत में । मैंने स्पष्टीकरण को फ्रंट-लोड किया है, साथ ही इसे जाने से स्पष्ट करने के लिए।
मैथ्यू एम।

58

मानक C और C ++ में, शून्य-आकार के सरणी की अनुमति नहीं है ।।

यदि आप GCC का उपयोग कर रहे हैं, तो इसे -pedanticविकल्प के साथ संकलित करें । यह चेतावनी देते हुए कहेगा:

zero.c:3:6: warning: ISO C forbids zero-size array 'a' [-pedantic]

C ++ के मामले में, यह समान चेतावनी देता है।


9
विज़ुअल सी ++ 2010 में:error C2466: cannot allocate an array of constant size 0
मार्क रैनसम

4
-जोरर बस सभी चेतावनियों को त्रुटियों में बदल देता है, जो जीसीसी कंपाइलर के गलत व्यवहार को ठीक नहीं करता है।
लुंडिन

C ++ बिल्डर 2009 भी सही ढंग से एक त्रुटि देता है:[BCC32 Error] test.c(3): E2021 Array must have at least one element
लंडिन

1
इसके बजाय -pedantic -Werror, आप बस भी कर सकते हैं-pedantic-errors
स्टीफन डॉलबर्ग

3
एक शून्य-आकार की सरणी शून्य-आकार के समान समान नहीं है std::array। (एक तरफ: मुझे याद है लेकिन वीएलएएस स्रोत पर विचार नहीं किया जा सकता है और सी ++ में होने से स्पष्ट रूप से खारिज कर दिया गया है।)

27

यह पूरी तरह से अवैध है, और हमेशा रहा है, लेकिन त्रुटि का संकेत देने के लिए बहुत सारे संकलनकर्ता उपेक्षा करते हैं। मुझे यकीन नहीं है कि आप ऐसा क्यों करना चाहते हैं। एक बूलियन से एक संकलन समय त्रुटि को ट्रिगर करने के लिए मुझे जो पता है, वह है:

char someCondition[ condition ];

यदि conditionगलत है, तो मुझे एक संकलन समय त्रुटि मिलती है। क्योंकि संकलक इसे अनुमति देते हैं, हालांकि, मैंने उपयोग करने के लिए लिया है:

char someCondition[ 2 * condition - 1 ];

यह 1 या -1 का आकार देता है, और मुझे ऐसा कंपाइलर कभी नहीं मिला है जो -1 का आकार स्वीकार करे।


यह इसके लिए उपयोग करने के लिए एक दिलचस्प हैक है।
एलेक्स कोय

10
मुझे लगता है कि यह मेटाप्रोग्रामिंग में एक आम चाल है। मुझे आश्चर्य नहीं होगा अगर STATIC_ASSERTइसे इस्तेमाल करने के कार्यान्वयन ।
जेम्स कांज़

सिर्फ क्यों नहीं:#if condition \n #error whatever \n #endif
जेरोफ़ोव 2

1
@ जेरोफ़ोव 2 क्योंकि स्थिति प्रीप्रोसेसिंग समय पर नहीं जानी जा सकती है, केवल संकलन समय
rmeador

9

मैं जोड़ता हूँ कि इस तर्क पर gcc के ऑनलाइन दस्तावेज़ का एक पूरा पृष्ठ है।

कुछ उद्धरण:

जीएनयू सी में शून्य-लंबाई सरणियों की अनुमति है।

ISO C90 में, आपको सामग्री को 1 की लंबाई देना होगा

तथा

3.0 से पहले के जीसीसी संस्करणों ने शून्य-लंबाई सरणियों को वैधानिक रूप से आरंभ करने की अनुमति दी, जैसे कि वे लचीली सरणियाँ थीं। उन मामलों के अलावा, जो उपयोगी थे, इसने उन स्थितियों में भी आरंभीकरण की अनुमति दी जो बाद के डेटा को भ्रष्ट करेंगे

तो आप कर सकते हैं

int arr[0] = { 1 };

और बूम :-)


क्या मैं ऐसा कर सकता हूँ int a[0], फिर a[0] = 1 a[1] = 2??
सूरज जैन

2
अगर आप अपने स्टैक को ओवरराइट करना चाहते हैं तो @SurajJain :-) C आपके द्वारा लिखी गई सरणी के सूचकांक बनाम आकार की जांच नहीं करता है, इसलिए आप कर सकते हैं a[100000] = 5लेकिन अगर आप भाग्यशाली हैं तो आप अपने ऐप को क्रैश कर देंगे, यदि आप भाग्यशाली हैं: -)
xanatos

इंट [को ०]; एक चर सरणी (शून्य आकार की सरणी) का मतलब है, मैं इसे अब कैसे निर्दिष्ट कर सकता हूं
सूरज जैन

@SurajJain "C जिस इंडेक्स को आप लिख रहे हैं उसका साइज़ बनाम" चेक नहीं करता "क्या स्पष्ट नहीं है? C में कोई इंडेक्स चेकिंग नहीं है, आप सरणी के अंत के बाद लिख सकते हैं और कंप्यूटर को क्रैश कर सकते हैं या अपनी मेमोरी के कीमती बिट्स को ओवरराइट कर सकते हैं। इसलिए यदि आपके पास 0 तत्वों की एक सरणी है, तो आप 0 तत्वों के अंत के बाद लिख सकते हैं।
xanatos


9

शून्य-लंबाई सरणियों का एक अन्य उपयोग चर-लंबाई की वस्तु (पूर्व- C99) बनाने के लिए है। शून्य लंबाई सरणियों हैं अलग से लचीला सरणियों [] 0 के बिना है जो।

Gcc doc से उद्धृत :

जीएनयू सी में शून्य-लंबाई सरणियों की अनुमति है। वे संरचना के अंतिम तत्व के रूप में बहुत उपयोगी हैं जो वास्तव में एक चर-लंबाई वाली वस्तु के लिए एक हेडर है:

 struct line {
   int length;
   char contents[0];
 };
 
 struct line *thisline = (struct line *)
   malloc (sizeof (struct line) + this_length);
 thisline->length = this_length;

ISO C99 में, आप एक लचीले सरणी सदस्य का उपयोग करेंगे, जो वाक्य रचना और शब्दार्थ में थोड़ा अलग है:

  • लचीले सरणी सदस्यों को 0 के बिना सामग्री [] के रूप में लिखा जाता है।
  • लचीले सरणी सदस्यों के पास अपूर्ण प्रकार है, और इसलिए आकार ऑपरेटर लागू नहीं किया जा सकता है।

एक वास्तविक दुनिया उदाहरण में शून्य-लंबाई सरणियों struct kdbus_itemहै kdbus.h (एक लिनक्स कर्नेल मॉड्यूल) ।


2
IMHO, मानक के लिए शून्य-लंबाई सरणियों के लिए मना करने का कोई अच्छा कारण नहीं था; यह एक संरचना के सदस्यों के रूप में शून्य आकार की वस्तुओं को ठीक कर सकता है और उन्हें void*अंकगणित के प्रयोजनों के लिए माना जाता है (इसलिए शून्य आकार के ऑब्जेक्ट में संकेत जोड़ना या घटाना निषिद्ध होगा)। जबकि लचीले ऐरे सदस्य ज्यादातर शून्य-आकार के सरणियों से बेहतर होते हैं, वे अतिरिक्त रूप से "सिंटेक्टिक" के अतिरिक्त स्तर को जोड़ने के बिना चीज़ों के लिए "संघ" के रूप में कार्य कर सकते हैं जो निम्नानुसार अप्रत्यक्ष रूप से होता है (जैसे दिए गए struct foo {unsigned char as_bytes[0]; int x,y; float z;}सदस्यों तक पहुंच सकता है x।) z...
सुपरकैट

... बिना किसी प्रकार के सीधे कहने के लिए myStruct.asFoo.x, आदि। आगे, IIRC, सी किसी भी प्रयास में एक संरचना के भीतर एक लचीली सरणी सदस्य को शामिल करने का प्रयास करते हैं, इस प्रकार यह असंभव बना देता है जिसमें एक संरचना है जिसमें ज्ञात लंबाई के कई अन्य लचीले-सरणी सदस्य शामिल हैं। सामग्री।
सुपरकट

@supercat एक अच्छा कारण नियम की अखंडता को बनाए रखने के लिए है बाहरी सीमा सीमाओं तक पहुँचने के बारे में। एक संरचना के अंतिम सदस्य के रूप में, C99 लचीला सरणी सदस्य GCC शून्य-आकार के सरणी के समान प्रभाव प्राप्त करता है, लेकिन अन्य मामलों में विशेष मामलों को जोड़ने की आवश्यकता के बिना। IMHO यह एक सुधार है जो sizeof x->contentsISO सी में एक त्रुटि है क्योंकि gcc में 0 वापस करने के विपरीत। शून्य आकार के सरणियाँ जो कि संरचनात्मक सदस्य नहीं हैं, अन्य समस्याओं का एक समूह है।
MM

@MM: दो समान बिंदुओं को शून्य-आकार की वस्तु में घटाने पर वे क्या समस्याएँ उत्पन्न करेंगे, जिन्हें उपज शून्य के रूप में परिभाषित किया गया था (जैसा कि वस्तु के किसी भी आकार के बराबर बिंदुओं को घटाया जाएगा), और असमान बिंदुओं को शून्य-आकार की वस्तुओं में घटाने के लिए उपज के रूप में परिभाषित किया गया था। अनिर्दिष्ट मूल्य? यदि मानक ने निर्दिष्ट किया था कि एक कार्यान्वयन एक FAM युक्त संरचना को किसी अन्य संरचना के भीतर एम्बेड करने की अनुमति दे सकता है बशर्ते कि बाद वाली संरचना में अगला तत्व या तो एक सरणी है जिसमें FAM के समान तत्व प्रकार हो या ऐसी सरणी के साथ शुरू होने वाली संरचना हो , और बशर्ते कि ...
19

... यह एएएम को सरणी के रूप में पहचानता है (यदि संरेखण नियमों के कारण विभिन्न कार्यालयों में लैंडिंग करना होगा, तो नैदानिक ​​की आवश्यकता होगी), जो बहुत उपयोगी होगा। जैसा कि यह है, वहाँ एक तरीका है जो सामान्य प्रारूप की संरचनाओं को संकेत स्वीकार करते struct {int n; THING dat[];}हैं और स्थिर या स्वत: अवधि की चीजों के साथ काम कर सकते हैं करने के लिए कोई अच्छा तरीका है ।
सुपरकट

6

संरचना के भीतर शून्य-आकार की सरणी घोषणाएं उपयोगी होंगी यदि उन्हें अनुमति दी गई है, और यदि शब्दार्थ ऐसे थे (1) वे संरेखण को बाध्य करेंगे, लेकिन अन्यथा किसी भी स्थान को आवंटित नहीं करेंगे, और (2) सरणी को अनुक्रमित करना परिभाषित व्यवहार माना जाएगा। ऐसा मामला जहां परिणामी सूचक मेमोरी के उसी ब्लॉक के भीतर होगा जो संरचना के रूप में है। इस तरह के व्यवहार को किसी भी सी मानक द्वारा अनुमति नहीं दी गई थी, लेकिन कुछ पुराने कंपाइलरों ने कंपार्टमेंट्स के लिए मानक बनने से पहले इसे खाली ब्रैकेट के साथ अपूर्ण सरणी घोषणाओं की अनुमति देने के लिए अनुमति दी थी।

संरचना हैक, जैसा कि आमतौर पर आकार 1 की एक सरणी का उपयोग करके कार्यान्वित किया जाता है, डोडी है और मुझे नहीं लगता कि कोई आवश्यकता है जो संकलक इसे तोड़ने से बचते हैं। उदाहरण के लिए, मैं उम्मीद होती है कि अगर एक संकलक देखता है int a[1], यह संबंध के लिए अपने अधिकार के भीतर हो जाएगा a[i]के रूप में a[0]। अगर कोई इस तरह के माध्यम से संरचना हैक के संरेखण मुद्दों के आसपास काम करने की कोशिश करता है

टंकण संरचना {
  uint32_t आकार;
  uint8_t डेटा [4]; // संरचना के आकार को फेंकने से बचने के लिए चार का उपयोग करें
}

एक संकलक चालाक हो सकता है और मान सकता है कि सरणी आकार वास्तव में चार है:

; जैसा लिखा गया है
  foo = myStruct-> data [i];
; जैसा कि व्याख्या की गई (थोड़ा-सा एंडियन हार्डवेयर मानकर)
  foo = ((* (uint32_t *) myStruct-> data) >> ((<< 3)) & 0xFF;

ऐसा अनुकूलन उचित हो सकता है, खासकर यदि myStruct->dataउसे उसी ऑपरेशन में रजिस्टर में लोड किया जा सकता है myStruct->size। मुझे पता है कि मानक में ऐसा कुछ भी नहीं है जो इस तरह के अनुकूलन को मना करे, हालांकि यह किसी भी कोड को तोड़ देगा, जो चौथे तत्व से परे सामान तक पहुंचने की उम्मीद कर सकता है।


1
लचीला सरणी सदस्य struct हैक के एक वैध संस्करण के रूप में C99 के लिए जोड़ा गया
एम.एम.

मानक कहता है कि विभिन्न सरणी सदस्यों तक पहुंच संघर्ष नहीं करती है, जो उस अनुकूलन को असंभव बना देगा।
बेन वोइग्ट

@BenVoigt: सी भाषा मानक एक बाइट लिखने और एक शब्द के साथ एक साथ पढ़ने के प्रभाव को निर्दिष्ट नहीं करता है, लेकिन 99.9% प्रोसेसर यह निर्दिष्ट करते हैं कि लेखन सफल होगा और शब्द में नया या पुराना संस्करण होगा। बाइट अन्य बाइट्स की अनसाल्टेड सामग्री के साथ। यदि एक कंपाइलर ऐसे प्रोसेसर को लक्षित करता है, तो संघर्ष क्या होगा?
सुपरकैट

@supercat: सी भाषा मानक गारंटी देता है कि एक साथ दो अलग-अलग सरणी तत्वों को लिखते हैं, संघर्ष नहीं करेंगे। तो आपका तर्क है कि (लिखते हुए पढ़ें) ठीक काम करता है, पर्याप्त नहीं है।
बेन वोइगट

@BenVoigt: यदि कोड का एक टुकड़ा उदाहरण के लिए सरणी तत्वों 0, 1 और 2 को किसी क्रम में लिखना था, तो इसे सभी चार तत्वों को एक लंबे समय में पढ़ने, तीन को संशोधित करने और चारों को वापस लिखने की अनुमति नहीं होगी, लेकिन मैं लगता है कि इसे सभी चार को एक लंबे समय में पढ़ने की अनुमति होगी, तीन को संशोधित करें, निचले 16 बिट्स को संक्षिप्त रूप में लिखें, और बाइट्स के रूप में बिट्स 16-23। क्या आप इससे असहमत होंगे? और कोड जिसे केवल सरणी के तत्वों को पढ़ने की आवश्यकता थी, उन्हें केवल एक लंबे समय तक पढ़ने और उस का उपयोग करने की अनुमति होगी।
सुपरकाट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.