हां, कई परिवर्तन हैं जो समान कोड के कारण C ++ 03 और C ++ 11 के बीच भिन्न व्यवहार का परिणाम देंगे। अनुक्रमण नियम अंतर कुछ दिलचस्प बदलावों के लिए करते हैं, जिनमें कुछ पहले से अपरिभाषित व्यवहार अच्छी तरह से परिभाषित होते हैं।
1. एक आरंभिक सूची के भीतर एक ही चर के कई म्यूटेशन
एक बहुत ही दिलचस्प कोने का मामला एक प्रारंभिक चर के भीतर एक ही चर के कई परिवर्तन होगा, उदाहरण के लिए:
int main()
{
int count = 0 ;
int arrInt[2] = { count++, count++ } ;
return 0 ;
}
C ++ 03 और C ++ 11 दोनों में यह अच्छी तरह से परिभाषित है लेकिन C ++ 03 में मूल्यांकन का क्रम अनिर्दिष्ट है लेकिन C ++ 11 में उनका मूल्यांकन उस क्रम में किया जाता है जिसमें वे दिखाई देते हैं । इसलिए यदि हम clang
C ++ 03 मोड में इसका उपयोग करते हैं, तो यह निम्नलिखित चेतावनी प्रदान करता है ( इसे लाइव देखें ):
warning: multiple unsequenced modifications to 'count' [-Wunsequenced]
int arrInt[2] = { count++, count++ } ;
^ ~~
लेकिन C ++ 11 में एक चेतावनी प्रदान नहीं करता है ( इसे लाइव देखें )।
2. नए अनुक्रमण नियम I = ++ i + 1 बनाते हैं; C ++ 11 में अच्छी तरह से परिभाषित
C ++ 03 के बाद अपनाए गए नए अनुक्रमण नियम का अर्थ है:
int i = 0 ;
i = ++ i + 1;
C ++ 11 में अब अपरिभाषित व्यवहार नहीं है, यह दोष रिपोर्ट 637 में शामिल है । अनुक्रमण नियम और उदाहरण असहमत
3. नए अनुक्रमण नियम भी ++++ i बनाते हैं; C ++ 11 में अच्छी तरह से परिभाषित
C ++ 03 के बाद अपनाए गए नए अनुक्रमण नियम का अर्थ है:
int i = 0 ;
++++i ;
C ++ 11 में अब अपरिभाषित व्यवहार नहीं है।
4. थोड़ा और अधिक संवेदनशील वामपंथी बदलाव पर हस्ताक्षर किए
C ++ 11 के बाद के ड्राफ्ट में वे शामिल हैं N3485
जो मैं नीचे दिए गए लिंक को एक बिट बिट को साइन बिट में शिफ्ट करने के अपरिभाषित व्यवहार को तय करता हूं । यह भी दोष रिपोर्ट 1457 में शामिल है । हॉवर्ड हिनांत ने थ्रेड में इस बदलाव के महत्व पर टिप्पणी की है कि क्या वाम-स्थानांतरण (<<) C ++ 11 में एक नकारात्मक पूर्णांक अपरिभाषित व्यवहार है? ।
5. कब्ज कार्यों को C ++ 11 में संकलित समय निरंतर अभिव्यक्तियों के रूप में माना जा सकता है
C ++ 11 ने कॉन्स्टैक्सप्र क्रिया शुरू की जो:
कॉन्स्ट्रेक्स स्पेसियर यह घोषणा करता है कि संकलन समय पर फ़ंक्शन या चर के मूल्य का मूल्यांकन करना संभव है। इस तरह के चर और कार्यों का उपयोग तब किया जा सकता है जहां केवल संकलन समय स्थिर अभिव्यक्ति की अनुमति है।
जबकि C ++ 03 में कॉन्स्टैक्सप्रिसेस की सुविधा नहीं है, क्योंकि हमें कॉस्टेक्सप्राइस कीवर्ड का उपयोग करने की आवश्यकता नहीं है क्योंकि मानक लाइब्रेरी C ++ 11 में कॉन्स्टैक्स के रूप में कई फ़ंक्शन प्रदान करती है । उदाहरण के लिए std :: num_limits :: min । उदाहरण के लिए, विभिन्न व्यवहार हो सकते हैं:
#include <limits>
int main()
{
int x[std::numeric_limits<unsigned int>::min()+2] ;
}
clang
C ++ 03 का उपयोग x
करने से यह एक परिवर्तनशील लंबाई सरणी बन जाएगा , जो एक विस्तार है और निम्नलिखित चेतावनी उत्पन्न करेगा:
warning: variable length arrays are a C99 feature [-Wvla-extension]
int x[std::numeric_limits<unsigned int>::min()+2] ;
^
जबकि C ++ 11 std::numeric_limits<unsigned int>::min()+2
में एक संकलन समय स्थिर अभिव्यक्ति है और इसे वीएलए विस्तार की आवश्यकता नहीं है।
6. C ++ 11 में अपवाद अपवाद विशिष्ट रूप से आपके विध्वंसक के लिए उत्पन्न होते हैं
चूंकि C ++ 11 उपयोगकर्ता परिभाषित डिस्ट्रॉक्टरnoexcept(true)
में निहित विनिर्देशन है जैसा कि noexcept डिस्ट्रक्टर्स में बताया गया है इसका मतलब है कि निम्नलिखित कार्यक्रम:
#include <iostream>
#include <stdexcept>
struct S
{
~S() { throw std::runtime_error(""); } // bad, but acceptable
};
int main()
{
try { S s; }
catch (...) {
std::cerr << "exception occurred";
}
std::cout << "success";
}
C ++ 11 में कॉल करेगा std::terminate
लेकिन C ++ 03 में सफलतापूर्वक चलेगा।
7. C ++ 03 में, टेम्पलेट तर्क में आंतरिक संबंध नहीं हो सकता है
यह क्यों std में अच्छी तरह से कवर किया गया है :: सॉर्ट स्वीकार नहीं करता है एक फ़ंक्शन के भीतर घोषित वर्गों की तुलना करें । तो निम्नलिखित कोड C ++ 03 में काम नहीं करना चाहिए:
#include <iostream>
#include <vector>
#include <algorithm>
class Comparators
{
public:
bool operator()(int first, int second)
{
return first < second;
}
};
int main()
{
class ComparatorsInner : public Comparators{};
std::vector<int> compares ;
compares.push_back(20) ;
compares.push_back(10) ;
compares.push_back(30) ;
ComparatorsInner comparatorInner;
std::sort(compares.begin(), compares.end(), comparatorInner);
std::vector<int>::iterator it;
for(it = compares.begin(); it != compares.end(); ++it)
{
std::cout << (*it) << std::endl;
}
}
लेकिन वर्तमान में clang
इस कोड को चेतावनी के साथ C ++ 03 मोड में अनुमति देता है जब तक कि आप -pedantic-errors
ध्वज का उपयोग नहीं करते हैं , जो कि icky है, इसे लाइव देखें ।
8. कई टेम्प्लेटों को बंद करते समय वह बीमार नहीं होता है
>>
कई टेम्प्लेट बंद करने का उपयोग करना अब बीमार नहीं है, लेकिन C ++ 03 और C + 11 में विभिन्न परिणामों के साथ कोड को जन्म दे सकता है। नीचे दिए गए उदाहरण को सही कोण कोष्ठक और पीछे की संगतता से लिया गया है :
#include <iostream>
template<int I> struct X {
static int const c = 2;
};
template<> struct X<0> {
typedef int c;
};
template<typename T> struct Y {
static int const c = 3;
};
static int const c = 4;
int main() {
std::cout << (Y<X<1> >::c >::c>::c) << '\n';
std::cout << (Y<X< 1>>::c >::c>::c) << '\n';
}
और C ++ 03 में परिणाम है:
0
3
और C ++ 11 में:
0
0
9. सी ++ 11 एसटीडी के कुछ परिवर्तन :: वेक्टर कंस्ट्रक्टर
इस उत्तर से थोड़ा संशोधित कोड दिखाता है कि std से निम्न निर्माणकर्ता का उपयोग कर :: वेक्टर :
std::vector<T> test(1);
C ++ 03 और C ++ 11 में अलग-अलग परिणाम उत्पन्न करता है:
#include <iostream>
#include <vector>
struct T
{
bool flag;
T() : flag(false) {}
T(const T&) : flag(true) {}
};
int main()
{
std::vector<T> test(1);
bool is_cpp11 = !test[0].flag;
std::cout << is_cpp11 << std::endl ;
}
10. शुरुआती इनिशियलाइज़र में रूपांतरणों को कम करना
C ++ 11 में एग्रीगेट इनिशियलाइज़र में एक संकरा रूपांतरण बीमार है और ऐसा लगता है gcc
कि यह C ++ 11 और C ++ 03 दोनों में इसकी अनुमति देता है, हालांकि यह C ++ 11 में डिफ़ॉल्ट रूप से एक चेतावनी प्रदान करता है:
int x[] = { 2.0 };
यह C ++ 11 मानक अनुभाग 8.5.4
सूची-आरंभ पैराग्राफ 3 के मसौदे में शामिल है :
किसी वस्तु या प्रकार T के संदर्भ की सूची को इस प्रकार परिभाषित किया गया है:
और निम्नलिखित बुलेट ( जोर मेरा ) में शामिल हैं:
अन्यथा, यदि टी एक वर्ग प्रकार है, तो कंस्ट्रक्टरों पर विचार किया जाता है। लागू निर्माण करने वालों की गणना की जाती है और सबसे अच्छा एक अधिभार संकल्प (13.3, 13.3.1.7) के माध्यम से चुना जाता है। यदि किसी भी तर्क को परिवर्तित करने के लिए एक संकीर्ण रूपांतरण (नीचे देखें) की आवश्यकता है, तो कार्यक्रम बीमार है
यह और कई और उदाहरण C ++ मानक अनुभाग annex C.2
C ++ और ISO C ++ 2003 के मसौदे में शामिल हैं । इसमें ये भी शामिल हैं:
नए प्रकार के स्ट्रिंग शाब्दिक [...] विशेष रूप से, आर, यू 8, यू 8 आर, यू, यूआर, यू, यूआर, या एलआर नामक मैक्रो का विस्तार नहीं किया जाएगा जब एक स्ट्रिंग शाब्दिक के निकट होगा, लेकिन स्ट्रिंग शाब्दिक के हिस्से के रूप में व्याख्या की जाएगी। । उदाहरण के लिए
#define u8 "abc"
const char *s = u8"def"; // Previously "abcdef", now "def"
उपयोगकर्ता-परिभाषित शाब्दिक स्ट्रिंग समर्थन [...] पहले, # 1 में दो अलग-अलग प्रीप्रोसेसिंग टोकन शामिल होंगे और मैक्रो _x का विस्तार किया गया होगा। इस अंतर्राष्ट्रीय मानक में, # 1 में एकल प्रीप्रोसेसिंग टोकन होते हैं, इसलिए मैक्रो का विस्तार नहीं किया जाता है।
#define _x "there"
"hello"_x // #1
पूर्णांक / और% [...] 2003 कोड के पूर्णांक विभाजन के परिणामों को निर्दिष्ट करें, जो पूर्णांक विभाजन का उपयोग करता है परिणाम को 0 या नकारात्मक अनंत की ओर ले जाता है, जबकि यह अंतर्राष्ट्रीय मानक हमेशा परिणाम को 0 की ओर गोल करता है।
आकार की जटिलता () सदस्य कार्य अब निरंतर [...] कुछ कंटेनर कार्यान्वयन जो C ++ 2003 के अनुरूप हैं, वे इस अंतर्राष्ट्रीय मानक में निर्दिष्ट आकार () आवश्यकताओं के अनुरूप नहीं हो सकते हैं। कंटेनरों को समायोजित करना जैसे std :: कड़ी आवश्यकताओं के लिए सूची में असंगत परिवर्तन की आवश्यकता हो सकती है।
Std का बेस क्लास बदलें :: ios_base :: विफलता [...] std :: ios_base :: विफलता अब सीधे std से नहीं निकली है :: अपवाद, लेकिन अब std से ली गई है :: system_error, जो बदले में से ली गई है std :: runtime_error। मान्य C ++ 2003 कोड जो मानता है कि std :: ios_base :: विफलता सीधे std से ली गई है :: अपवाद इस अंतर्राष्ट्रीय मानक में अलग तरह से निष्पादित हो सकता है।
auto
है कि इस तरह की स्थिति में परिणाम हो सकता है