"फ़ाइल के अंत में कोई नई पंक्ति नहीं" संकलक चेतावनी


187

कुछ C ++ कंपाइलर्स में निम्नलिखित चेतावनी का कारण क्या है?

फ़ाइल के अंत में कोई नई पंक्ति नहीं

मुझे स्रोत / हेडर फ़ाइल के अंत में एक खाली रेखा क्यों होनी चाहिए?


17
वास्तव में कारण नहीं है, लेकिन यह बहुत कष्टप्रद है अगर आप catएक फाइल करते हैं और इसमें एक अनुगामी न्यूलाइन नहीं है क्योंकि नया शेल प्रॉम्प्ट फाइल की अंतिम पंक्ति (यानी कॉलम 0 में नहीं) के बाद दिखाई देगा
ThiefMaster

@ThiefMaster मेरा $ PS1 उसी कारण से एक नई पंक्ति के साथ शुरू होता है। (यह वैसे भी एक मल्टी लाइन प्रॉम्प्ट है, जिसमें एक लाइन पर उपयोगी जानकारी का एक गुच्छा होता है और फिर कुछ नहीं होता है, लेकिन अगले पर एक त्वरित चरित्र होता है ताकि काफी लंबी कमांड लपेटें नहीं)
bames53

7
Why should I have an empty line at the end of a source/header file- यदि किसी टेक्स्ट फाइल में सम्‍मिलित है one\ntwo\nthree\nतो इसमें तीन लाइनें हैं, जिनमें से कोई भी खाली नहीं है। यदि किसी पाठ फ़ाइल में सम्‍मिलित है one\ntwo\nthreeतो वह पाठ फ़ाइल नहीं है, उसी अर्थ में कि अंत में पूर्ण विराम के बिना एक वाक्य एक वाक्य नहीं है।
ब्रैंडिन

जवाबों:


217

कुछ समस्याओं के बारे में सोचें, जो कोई नई रेखा न होने पर हो सकती हैं। एएनएसआई मानक के अनुसार #includeशुरुआत में किसी फाइल का फाइल ठीक उसी तरह से फाइल को सम्मिलित करता है जैसे वह फाइल के सामने होता है और फाइल #include <foo.h>की सामग्री के बाद नई लाइन नहीं डालता है । इसलिए यदि आप पार्सर के अंत में कोई नई पंक्ति के साथ कोई फ़ाइल शामिल करते हैं तो इसे देखा जाएगा जैसे कि अंतिम पंक्ति foo.hपहली पंक्ति के समान लाइन पर है foo.cpp। क्या होगा अगर foo.h की अंतिम पंक्ति एक नई लाइन के बिना एक टिप्पणी थी? अब foo.cppटिप्पणी की पहली पंक्ति है। ये समस्याओं के प्रकारों के उदाहरण हैं, जो रेंग सकते हैं।


बस नीचे जेम्स के जवाब के लिए किसी भी इच्छुक पार्टियों को इंगित करना चाहता था। हालांकि, C के लिए उपरोक्त उत्तर अभी भी सही है, नए C ++ मानक (C ++ 11) को बदल दिया गया है, ताकि C ++ 11 के अनुरूप और C कंपाइलर का उपयोग करते समय यह चेतावनी जारी न की जाए।

जेम्स पोस्ट के माध्यम से C ++ 11 मानक से:

एक स्रोत फ़ाइल जो खाली नहीं है और जो एक नई-पंक्ति वर्ण में समाप्त नहीं होती है, या जो एक नए पंक्ति-वर्ण में समाप्त होती है, ऐसे किसी भी splicing के होने से पहले एक backslash वर्ण से पहले तुरंत समाप्त हो जाएगी, जैसे कि एक अतिरिक्त नया- फ़ाइल में लाइन वर्ण जोड़ा गया (C ++ 11 .22.2 / 1)।


28
बेशक हर कंपाइलर #include के बाद एक नई लाइन जोड़ता है। शुक्र है।
19

3
मुझे Microsoft Visual C ++ का पुराना संस्करण याद है (जैसे 2.x या कुछ और) में वास्तव में यह समस्या थी। यह तेज हो गया था क्योंकि आईडीई संपादक ने इस तरह के लापता-न्यूलाइन व्यवहार को प्रोत्साहित किया था।
ग्रेग हेविल जिल

2
कंपाइलर वर्तमान में शिकायत नहीं कर सकते हैं, लेकिन GitHub वास्तव में करता है।
पुइओवर

1
मैं जेम्स द्वारा "नीचे" उत्तर देख सकता हूं : लेकिन ऑर्डरबाय में "उपरोक्त उत्तर" क्या ?! ऊपर सवाल है, जैसा कि मैं आमतौर पर वोट से आदेश देता हूं। या आप अपने खुद के जवाब का मतलब है?
एमबीएक्स

@ थोमस: क्या यह कार्यक्रम अपरिभाषित व्यवहार को आमंत्रित करता है क्योंकि यह नई लाइन के साथ समाप्त नहीं होता है। : यहां कार्यक्रम देखें ideone.com/jswwf9
नाशक

44

आवश्यकता है कि हर स्रोत फ़ाइल एक गैर-बची हुई newline के साथ समाप्त हो जाती है C ++ 11 में हटा दिया गया था। विनिर्देश अब पढ़ता है:

एक स्रोत फ़ाइल जो खाली नहीं है और जो एक नई-पंक्ति वर्ण में समाप्त नहीं होती है, या जो एक नए पंक्ति-वर्ण में समाप्त होती है, ऐसे किसी भी splicing के होने से पहले एक backslash वर्ण से पहले तुरंत समाप्त हो जाएगी, जैसे कि एक अतिरिक्त नया- फ़ाइल में लाइन वर्ण जोड़ा गया (C ++ 11 .22.2 / 1)।

एक अनुरूप संकलक को अब यह चेतावनी जारी नहीं करनी चाहिए (कम से कम तब नहीं जब C ++ 11 मोड में संकलित किया जाए, यदि कंपाइलर में भाषा विनिर्देश के विभिन्न संशोधनों के लिए मोड हैं)।


4
C ++ के लिए यह सब ठीक है और अच्छा है; दुर्भाग्य से, सी अभी भी कहते हैं कि यह यूबी है, यहां तक ​​कि आगामी सी 1 एक्स मानक के नवीनतम मसौदे में भी।
एडम रोसेनफील्ड

11
इस प्रश्न को टैग किया गया है [c ++] और नहीं [c]।
जेम्स मैकनेलिस

3
फिर भी, शायद इसे [c] टैग किया जाना चाहिए, क्योंकि C में इस चेतावनी को खोजने वाले कई लोग यहां अपना रास्ता खोज लेंगे।
एडम रोसेनफील्ड

1
यह अभी भी जोड़ने के लिए एक अच्छा बिंदु है। इसे ऊपर जोड़ना। आशा है कि आप बुरा नहीं मानेंगे
टीजे सीब्रुक

25

C ++ 03 मानक [2.1.1.2] घोषित:

... यदि कोई स्रोत फ़ाइल जो खाली नहीं है, एक नई-लाइन वर्ण में समाप्त नहीं होती है, या किसी भी ऐसे splicing के होने से पहले एक backslash चरित्र से पहले तुरंत एक नई-पंक्ति वर्ण में समाप्त होती है, तो व्यवहार अपरिभाषित है।


16

"आज्ञाकारी" का उत्तर है "क्योंकि C ++ 03 मानक का कहना है कि एक कार्यक्रम का व्यवहार न्यूलाइन में समाप्त नहीं होता है" अपरिभाषित है।

जिज्ञासु का उत्तर यहाँ है: http://gcc.gnu.org/ml/gcc/2001-07/msg01120.html


4
आह, प्रिय "अपरिभाषित व्यवहार"। जब अन्य भाषाएं विफल हो जाती हैं, तो c / c ++ "अपरिभाषित" तरीकों से व्यवहार करता है :) यही, निश्चित रूप से, उनके आकर्षण का एक बड़ा हिस्सा है। और मैं मजाक नहीं कर रहा हूं।
शीलेंट

6

यह एक रिक्त रेखा की बात नहीं कर रहा है, यह है कि क्या अंतिम पंक्ति (जिसमें सामग्री हो सकती है) एक नई पंक्ति के साथ समाप्त हो गई है।

अधिकांश टेक्स्ट एडिटर किसी फ़ाइल की अंतिम पंक्ति के अंत में एक नई पंक्ति लगाएंगे, इसलिए यदि अंतिम पंक्ति में एक नहीं है, तो एक जोखिम है कि फ़ाइल को काट दिया गया है। हालाँकि, मान्य कारण हैं कि आप नई लाइन नहीं चाहते हैं, इसलिए यह केवल एक चेतावनी है, त्रुटि नहीं।


5

#includeफ़ाइल की शाब्दिक सामग्री के साथ इसकी लाइन को बदल देगा। यदि फ़ाइल एक नई रेखा के साथ समाप्त नहीं होती है, तो उस लाइन को #includeखींचा जाता है जो अगली पंक्ति में विलय हो जाएगी।


2

मैं सी-फ्री आईडीई संस्करण 5.0 का उपयोग कर रहा हूं, मेरे या तो 'सी ++ ’या' सी’ भाषा के प्रोग्रेस में मुझे एक ही समस्या हो रही थी । प्रोग्राम के अंत में बस प्रोग्राम की अंतिम पंक्ति अर्थात कार्य की समाप्ति के बाद यह हो सकता है मुख्य या कोई फ़ंक्शन), एंटर- लाइन नंबर दबाएं । 1. उसी कार्यक्रम को अंजाम दिया जाएगा, यह बिना किसी त्रुटि के चलेगा।


2

बेशक हर कंपाइलर #include के बाद एक नई लाइन जोड़ता है। शुक्र है। - @mxcl

विशिष्ट C / C ++ नहीं, लेकिन C बोली: GL_ARB_shading_language_includeOS X पर glsl संकलक के विस्तार का उपयोग करते समय आप एक लापता नई रेखा के बारे में नहीं चेतावनी देते हैं । तो तुम एक लिख सकते हैं MyHeader.hएक हैडर गार्ड जो साथ समाप्त होता है के साथ फाइल #endif // __MY_HEADER_H__और आप करेंगे के बाद लाइन खोना #include "MyHeader.h"पक्का।


2

क्योंकि व्यवहार नई फ़ाइल के साथ समाप्त नहीं होता है, तो C / C ++ संस्करणों के बीच भिन्नता है। विशेष रूप से बुरा पुराने सी ++ है - संस्करण, सी ++ में एफएक्स 03 मानक कहते हैं (अनुवाद चरण):

यदि कोई स्रोत फ़ाइल जो खाली नहीं है, एक नई-लाइन के चरित्र में समाप्त नहीं होती है, या एक बैकस्लैश चरित्र से पहले तुरंत एक नई-पंक्ति के चरित्र में समाप्त होती है, तो व्यवहार अपरिभाषित है।

अनिर्धारित व्यवहार बुरा है: एक मानक अनुरूप संकलक अधिक या कम कर सकता है कि वह यहां क्या चाहता है (मैलिक कोड डालें या जो भी हो) - स्पष्ट रूप से चेतावनी का कारण।

जबकि स्थिति C ++ 11 में बेहतर है, यह उन परिस्थितियों से बचने के लिए एक अच्छा विचार है जहां व्यवहार पूर्व संस्करणों में अपरिभाषित है। C ++ 03 विनिर्देश C99 से भी बदतर है, जो इस तरह की फ़ाइलों को प्रतिबंधित करता है (व्यवहार तब परिभाषित किया गया है)।


मुझे संदेह है कि मानक ने कहा था कि बिना नई लाइन के प्रोग्राम्स ने अनफाइंड बिहेवियर किया है, बजाय इसके कि वे बीमार थे, यह बताते हुए कि कुछ कंपाइलर डायरेक्शन के बाद सोर्स कोड टेक्स्ट के साथ शामिल फाइल की नॉन-टर्मिनेटेड फाइनल लाइन को #includeअसेप्ट करेंगे। , और इस तरह के संकलक को लक्षित करने वाले कुछ प्रोग्रामर ने इस तरह के व्यवहार का फायदा उठाया हो सकता है। इस तरह की चीजों को मानक रूप से छोड़ने के कारण, अपरिभाषित कार्यक्रमों से ऐसे quirks का शोषण करने वाले प्लेटफार्मों पर अच्छी तरह से परिभाषित किया जा सकता है जो इस तरह के व्यवहार को निर्दिष्ट करते हैं। मानक जनादेश होने से इस तरह के कार्यक्रम टूट जाते हैं।
सुपरकैट

0

यह चेतावनी यह इंगित करने में भी मदद कर सकती है कि किसी फ़ाइल को किसी तरह से छोटा किया जा सकता था। यह सच है कि कंपाइलर किसी कंपाइलर त्रुटि को वैसे भी फेंक देगा - खासकर अगर यह एक फ़ंक्शन के बीच में है - या शायद एक लिंकर त्रुटि है, लेकिन ये अधिक क्रिप्टिक हो सकते हैं, और होने की गारंटी नहीं है।

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


-2

वह कोई त्रुटि नहीं है। यह सिर्फ एक चेतावनी है।

फ़ाइल को एक संपादक में खोलें, फ़ाइल की अंतिम पंक्ति पर जाएं, और फ़ाइल के अंत में एक रिक्त रेखा जोड़ने के लिए एंटर दबाएं।

हालांकि, इसके अलावा, आपको #include <iostream>इसके बजाय उपयोग करना चाहिए <iostream.h>। फिर इसके using std::cout;बाद इसमें डालें ।

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