संकलक इस चेतावनी को क्यों फेंक रहा है: "लापता इनिशिएटिव"? क्या संरचना आरंभिक नहीं है?


79

मैं किसी प्रोग्राम के लिए किसी प्रकार का फ्रंटएंड बना रहा हूं। प्रोग्राम को लॉन्च करने के लिए मैं कॉल का उपयोग कर रहा हूं CreateProcess(), जो अन्य चीजों के बीच एक STARTUPINFOसंरचना को एक संकेतक प्राप्त करता है । मैं जो संरचना करता था उसे आरंभ करने के लिए:

जीसीसी के साथ कार्यक्रम को संकलित करते हुए चेतावनियों के इन सेटों को सक्षम करने से -Wall -Wextraमुझे यह कहते हुए चेतावनी मिलती है कि पहली पंक्ति की ओर इशारा करते हुए एक लापता आरंभीकरण है।

इसलिए मैंने करना समाप्त कर दिया:

और इस तरह संकलक कोई चेतावनी नहीं देता है। सवाल यह है कि किसी संरचना को शुरू करने के इन तरीकों में क्या अंतर है? पहली विधि का उपयोग करना, क्या संरचना आरम्भिक नहीं है? तुम किसकी सिफारिश करना चाहोगे?


1
चेतावनी सिर्फ यह है कि: एक चेतावनी। इस विशिष्ट अवसर पर इस विशिष्ट चेतावनी को अनदेखा करना ठीक है। संकलक चेतावनी को ऐसे मामलों में आपकी मदद करने के लिए उत्सर्जित करता है: struct struct_with_four_fields x = {1, 2, 3};जहां 4 में से केवल 3 सदस्य आरंभिक हैं।
pmg

मेरी पिछली टिप्पणी में 4 वें सदस्य को 0.
pmg

5
लापता शुरुआती के बारे में चेतावनी सामान्य रूप से अनुचित नहीं है; यदि आपके पास 4 सदस्यों के साथ एक संरचना है और आप उनमें से केवल 3 के लिए इनिशियलाइज़र प्रदान करते हैं, तो यह एक गलती होने की संभावना है। लेकिन { 0 }सभी सदस्यों को शून्य से शुरू करने के लिए एक सामान्य और अच्छी तरह से परिभाषित मुहावरा है (प्रत्येक उप-सदस्य के लिए पुनरावर्ती रूप से परिभाषित) - यही वजह है कि बाद में जीसीसी के संस्करणों को उस विशेष मामले के बारे में चेतावनी देने के लिए संशोधित नहीं किया गया है।
कीथ थॉम्पसन

@KeithThompson आप किस बारे में बात कर रहे हैं? मैं gcc का उपयोग कर रहा हूँ 4.8.2 , और सवाल पाँच साल बीत जाने के बाद से। पुनश्च एक और मेल था, जिसे मैं अंत में लिंक करना चाहता हूं, लेकिन मेरे आश्चर्य के लिए यह गायब है। संभवतः मेल सर्वर सभी संदेशों को सहेजता नहीं है, यह दुखद है, मेल उस व्यक्ति के लिए उपयोगी होगा जो समस्या को फिर से पूरा करता है।
हाय-एंजेल

4
@ हाय-एंजेल: जब मैं सोलारिस पर gcc-4.8.1 के साथ एक छोटा सा कार्यक्रम संकलित करता हूं, तो मुझे "चेतावनी: लापता इनिशाइज़र" मिलता है। जब मैं लिनक्स टकसाल पर gcc-4.8.2 के साथ एक ही कार्यक्रम संकलित करता हूं, तो मुझे चेतावनी नहीं मिलती है। संयोग से, आपके द्वारा लिंक किएobj = {0}; गए संदेश में लाइन सी मान्य नहीं है, और 4.8.2 gcc इसे सिंटैक्स त्रुटि के रूप में अस्वीकार करता है। यदि आप C ++ के रूप में संकलन कर रहे हैं, तो याद रखें कि यह एक अलग भाषा है, और gcc एक अलग फ्रंट एंड का उपयोग करता है; gcc के C कंपाइलर में फिक्स g ++ पर लागू हो भी सकता है और नहीं भी।
कीथ थॉम्पसन

जवाबों:


87

मेरी राय में बिना किसी अच्छे कारण के, जीसीसी केवल अत्यधिक पागल हो रहा है, लेकिन फिर यह निश्चित रूप से सच है कि सीसीसी की बारीकियों के बारे में जीसीसी के रखवाले बहुत अधिक जानते हैं।

जीसीसी मेलिंग सूची में समस्या के बारे में चर्चा के इस छोटे से धागे को देखें:

लब्बोलुआब यह है कि - संरचना को {0}प्रारंभिक रूप से शून्य करने से वास्तव में पूरी चीज को इनिशियलाइज़ किया जा सकेगा।

C99 मानक का कहना है कि 6.7.8 / 21 में निम्नलिखित "प्रारंभिक - अर्थमिति":

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

C90 का कहना है कि 6.5.7 में थोड़ा अलग शब्दांकन के साथ समान है (दूसरे शब्दों में, C99 ने यहां कुछ नया नहीं जोड़ा है)।

यह भी ध्यान दें कि C ++ में इसे बढ़ाया गया था, ताकि ब्रेसिज़ का एक खाली सेट, " {}", किसी ऑब्जेक्ट पर वैल्यू इनिशियलाइज़ेशन कर सके क्योंकि ऐसी स्थितियाँ (जैसे टेम्प्लेट) थीं जब आपको यह भी पता नहीं होगा कि सदस्य या कितने सदस्य एक प्रकार के हैं हो सकता है। तो न केवल यह अच्छा अभ्यास है, लेकिन कई बार एक शुरुआती सूची होना आवश्यक है जो किसी वस्तु के सदस्यों की संख्या से कम हो।


19
मुझे जोड़ना था -Wno-missing-field-initializersऔर -Wno-missing-bracesइसलिए कि जीजीसी ने मुझे = {0};अपनी संरचनाओं के लिए रखने के बारे में विलाप करना बंद कर दिया । क्या किसी को पता है कि इन चेतावनी को अक्षम करने से = {0};संरचनाओं के अलावा अन्य चीजों के लिए चेतावनी याद आएगी ?
मैट क्लार्कसन

4
फिक्स gcc 4.7.0 में मौजूद है , लेकिन 4.6.3 gcc में नहीं है ।
स्पाइसर

1
@ स्पर: कौन सा "ठीक"? इसके अलावा, मैं mingw32-g++.exe (GCC) 4.7.2ऊपर के मुहावरे (यहां तक ​​कि सटीक मामला STARTUPINFO) पर भी यह चेतावनी दे रहा हूं ।
जान हुदेक

2
@ जान हुडेक: संशोधन १85२an५ec । दुर्भाग्य से, मेरी पिछली टिप्पणियों के URL अब काम नहीं करते हैं। यहाँ बग फिक्स से जुड़ा है: gcc.gnu.org/bugzilla/show_bug.cgi?id=36750
splicer

9
मैं अभी भी gcc के साथ 4.9.3 से चेतावनी प्राप्त कर रहा हूँ, जब मेरे C ++ क्लासेस में खाली ब्रेस {}या {0}इनिशियलाइज़र का उपयोग कर रहा हूँ : /
कामिल Kisiel

21

इसे संरचना को आरंभ करके C ++ कार्यक्रमों में GCC के लिए आसानी से तय किया जा सकता है

  • अभी कुछ दिनों पहले ऐसा ही हुआ था

1
इस उत्तर के साथ एक संभावित नुकसान यह है कि C ++ 98 में इसने खेतों को शून्य-आरंभ नहीं किया। शून्य-प्रारंभिक व्यवहार C ++ 03 में जोड़ा गया था।
एमएम

1
@MM संभव नुकसान की ओर इशारा करने के लिए धन्यवाद, लेकिन मुझे लगता है कि दिसंबर 2018 में यह कोड किसी भी अधिक खतरनाक स्थिति में नहीं होना चाहिए। BTW, मुझे यह उत्तर सबसे अच्छा लगता है!
पीटर वारगा

@AlBundy दुर्भाग्य से अभी भी कुछ कंपाइलर हैं जो C ++ 98 इनिशियलाइज़ेशन का उपयोग करते हैं (जैसे C ++ बिल्डर XE5 32-बिट मोड जो कि अभी मेरे पास संयोग से खुला है)
MM

मुझे इसकी वजह से अपनी फ़ाइल में कोड की 10+ पंक्तियों को जोड़ना पड़ा। मैं वास्तव में गुस्से में हूं। फ़ंक्शन कॉल में अनाम ऑब्जेक्ट को पास करने की कोशिश की। यदि मैंने {} या {0} का उपयोग किया है, तो मुझे यह चेतावनी मिली (एक त्रुटि के रूप में माना गया)। अगर मैंने इस्तेमाल किया () तो gcc को लगता है कि यह एक फंक्शन कॉल है ...
bencemeszaros

15

आपने अधिक से अधिक चेतावनियों का उपयोग करने के लिए कहा -Wall -Wextra

इस मामले में, आपको एक चेतावनी मिलती है जो बताती है कि आपने सभी क्षेत्रों को निर्दिष्ट नहीं किया है, जो पूरी तरह से वैध है, लेकिन अनजाने में हो सकता है।

आप इस चेतावनी को जोड़कर दबा सकते हैं -Wno-missing-field-initializers


12

यह वेब पेज अंतर्निहित मुद्दे पर महान विस्तार से चर्चा करता है: http://ex-parrot.com/~chris/random/initialise.html

एक काम के आसपास के रूप में, मेरा वर्तमान समाधान चुनिंदा रूप से इस चेतावनी को दबाने के लिए है:

अफसोस की बात है कि यह केवल क्लैंग में काम करता है और जीसीसी में काम नहीं करता है।


4
मैं पुष्टि कर सकता हूं: #pragma GCC diagnostic ignored "-Wmissing-field-initializers"जीसीसी कंपाइलर 4.2.1 द्वारा स्वीकार किया जाता है, लेकिन कुछ भी नहीं। जीसीसी के नए संस्करणों के बारे में अनिश्चितता
मैक्सिम खोल्यकिन

1
@speakus, मैं यह पुष्टि कर सकता हूं कि यह नवीनतम (लेखन के समय) gcc (7.3.0) के साथ काम कर रहा है।
साइबरडे

@cydef अन्य टिप्पणियों के अनुसार और मैंने जो बग रिपोर्ट देखी है, जीसीसी अब इसके लिए (जीसीसी 5 के रूप में) बिल्कुल भी चेतावनी नहीं देता है - भले ही #pragma clang diagnostic ignored "-Wmissing-field-initializers"। अगर यह मामला है तो आपको शायद जांच करनी चाहिए।
WD40

1

C ++ में आप boost::initialized_valueइस चेतावनी से छुटकारा पाने के लिए उपयोग कर सकते हैं । मेरे पास चेतावनी है कि मैं बंद कर दूं boost; इसलिए मुझे नहीं पता कि क्या यह आपके मामले में किसी अन्य चेतावनी का कारण होगा। इस तरह आपको चेतावनी को अक्षम नहीं करना है।

उदाहरण:

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