සී ++ 98 සහ සී ++ 03
මෙම පිළිතුර C ++ ප්රමිතියේ පැරණි අනුවාද සඳහා ය. සම්මතයේ C ++ 11 සහ C ++ 14 අනුවාදවල විධිමත් ලෙස 'අනුක්රමික ලකුණු' අඩංගු නොවේ; මෙහෙයුම් 'පෙර අනුපිළිවෙලට' හෝ 'අනුක්රමික' හෝ 'අවිනිශ්චිත අනුපිළිවෙලට' ඇත. ශුද්ධ ආචරණය අත්යවශ්යයෙන්ම සමාන ය, නමුත් පාරිභාෂිතය වෙනස් ය.
වියාචනය : හරි. මෙම පිළිතුර ටිකක් දිගු ය. එබැවින් එය කියවන විට ඉවසීමෙන් කටයුතු කරන්න. ඔබ මේ දේවල් දැනටමත් දන්නවා නම්, ඒවා නැවත කියවීමෙන් ඔබට පිස්සු වැටෙන්නේ නැත.
පූර්ව අවශ්යතා : සී ++ ප්රමිතිය පිළිබඳ මූලික දැනුමක්
අනුක්රමික ස්ථාන යනු කුමක්ද?
ස්ටෑන්ඩර්ඩ් පවසයි
අනුක්රමික ලක්ෂ්ය ලෙස හැඳින්වෙන ක්රියාත්මක කිරීමේ අනුපිළිවෙලෙහි නිශ්චිත ස්ථානවල , පෙර ඇගයීම්වල සියලු අතුරු ආබාධ සම්පූර්ණ විය යුතු අතර පසුකාලීන ඇගයීම්වල අතුරු ආබාධ කිසිවක් සිදු නොවනු ඇත. (§1.9 / 7)
අතුරු ආබාධ? අතුරු ආබාධ මොනවාද?
ප්රකාශනයක් ඇගයීම මගින් යමක් නිපදවන අතර ඊට අමතරව ක්රියාත්මක කිරීමේ පරිසරයේ තත්වයෙහි වෙනසක් සිදුවුවහොත් ප්රකාශනයට (එහි ඇගයීමට) යම් අතුරු ආබාධයක් ඇති බව කියනු ලැබේ.
උදාහරණයක් වශයෙන්:
int x = y++; //where y is also an int
ආරම්භක මෙහෙයුමට අමතරව ක්රියාකරුගේ y
අතුරු ආබාධය හේතුවෙන් වටිනාකම වෙනස් ++
වේ.
මේ වනතෙක් ගොඩක් හොඳයි. අනුක්රමික ස්ථාන කරා ගමන් කිරීම. Comp.lang.c කර්තෘ විසින් ලබා දී ඇති seq-points වල විකල්ප අර්ථ දැක්වීම Steve Summit
:
අනුක්රමික ලක්ෂ්යය යනු දූවිලි සමනය වී ඇති කාල පරිච්ඡේදයක් වන අතර මෙතෙක් දැක ඇති සියලුම අතුරු ආබාධ සම්පූර්ණ බව සහතික කෙරේ.
සී ++ ප්රමිතියේ ලැයිස්තුගත කර ඇති පොදු අනුක්රමික කරුණු මොනවාද?
ඒවා:
පූර්ණ ප්රකාශනය ඇගයීම අවසානයේ ( §1.9/16
) (පූර්ණ ප්රකාශනය යනු වෙනත් ප්රකාශනයක උප ප්රකාශනයක් නොවන ප්රකාශනයකි.) 1
උදාහරණයක් :
int a = 5; // ; is a sequence point here
පළමු ප්රකාශනය ( §1.9/18
) 2 ඇගයීමෙන් පසු පහත සඳහන් එක් එක් ප්රකාශනය ඇගයීමේදී
a && b (§5.14)
a || b (§5.15)
a ? b : c (§5.16)
a , b (§5.18)
(මෙහි a, b කොමා ක්රියාකරු ය; දී func(a,a++)
,
කොමා ක්රියාකරු නොවේ, එය හුදෙක් තර්ක අතර වෙන්කර තියෙන්නේ a
හා a++
ඒ අනුව හැසිරීම එම නඩුව (නම් නිර්වචනය නොකළ ඇත. a
ප්රාථමික වර්ගය ලෙස සැලකේ))
ශ්රිත ඇමතුමකදී (ශ්රිතය පේළිගතව පවතීද නැද්ද යන්න), ශ්රිත ශරීරයේ කිසියම් ප්රකාශනයක් හෝ ප්රකාශයක් ක්රියාත්මක කිරීමට පෙර සිදුවන සියලුම ශ්රිත තර්ක (ඇත්නම්) ඇගයීමෙන් පසුව ( §1.9/17
).
1: සටහන: පූර්ණ ප්රකාශනයක ඇගයීම සඳහා පූර්ණ ප්රකාශනයේ ශබ්දකෝෂයේ කොටසක් නොවන උප ප්රකාශන ඇගයීම ඇතුළත් කළ හැකිය. නිදසුනක් ලෙස, පෙරනිමි තර්ක ප්රකාශන (8.3.6) තක්සේරු කිරීමට සම්බන්ධ උප ප්රකාශන, ශ්රිතය ලෙස හඳුන්වන ප්රකාශනය තුළ නිර්මාණය කරන ලද්දක් ලෙස සලකනු ලැබේ, පෙරනිමි තර්කය අර්ථ දක්වන ප්රකාශනය නොවේ
2: 5 වන වගන්තියේ විස්තර කර ඇති පරිදි, ක්රියාකරවන්නන් ගොඩනංවන ලද ක්රියාකරුවන් වේ. මෙම ක්රියාකරුවන්ගෙන් එක් අයෙකු වලංගු සන්දර්භයක් තුළ (13 වන වගන්තිය) අධික ලෙස පටවන විට, පරිශීලක අර්ථ දක්වන ලද ක්රියාකරු ශ්රිතයක් නම් කරන විට, ප්රකාශනය මඟින් ක්රියාකාරී ආයාචනයක් සහ ඔපෙරන්ඩ්ස් තර්ක ලැයිස්තුවක් සාදයි, ඒවා අතර අනුක්රමික ලක්ෂ්යයක් නොමැතිව.
නිර්වචනය නොකළ හැසිරීම යනු කුමක්ද?
ස්ටෑන්ඩර්ඩ් වගන්තිය අනිශ්චිත හැසිරීම නිර්වචනය §1.3.12
ලෙස
හැසිරීම, එවැනි සඳහා මෙම ජාත්යන්තර සම්මත පනවයි, වැරදි වැඩ ඉදිකිරීමක් හෝ වැරදි සහගත දත්ත භාවිතය මත මතු විය ලෙස කිසිදු අවශ්යතා 3 .
මෙම අන්තර්ජාතික ප්රමිතිය මගින් හැසිරීම පිළිබඳ කිසියම් පැහැදිලි අර්ථ දැක්වීමක් මඟ හැරෙන විට නිර්වචනය නොකළ හැසිරීම ද අපේක්ෂා කළ හැකිය.
3: අවසර ලත් නිර්වචනය නොකළ හැසිරීම, අනපේක්ෂිත ප්රති results ල සමඟ තත්වය නොසලකා හැරීම, පරිවර්තන හෝ වැඩසටහන් ක්රියාත්මක කිරීමේදී පරිසරයේ ලක්ෂණයක් ලෙස ලේඛනගත ආකාරයකින් හැසිරීම (රෝග විනිශ්චය පණිවිඩයක් නිකුත් කිරීම සමඟ හෝ නැතිව), පරිවර්තනයක් හෝ ක්රියාත්මක කිරීමක් අවසන් කිරීම දක්වා පරාසයක පවතී. (රෝග විනිශ්චය පණිවිඩයක් නිකුත් කිරීමත් සමඟ).
කෙටියෙන් කිවහොත්, නිර්වචනය නොකළ හැසිරීම යනු ඔබේ නාසයෙන් පියාසර කරන ඩීමන් සිට ඔබේ පෙම්වතිය ගැබ් ගැනීම දක්වා ඕනෑම දෙයක් සිදුවිය හැකිය.
නිර්වචනය නොකළ හැසිරීම සහ අනුක්රමික ස්ථාන අතර ඇති සම්බන්ධය කුමක්ද?
මා එයට පිවිසීමට පෙර නිර්වචනය නොකළ හැසිරීම, නිශ්චිතව දක්වා නැති හැසිරීම සහ ක්රියාත්මක කිරීමේ නිර්වචනය කළ හැසිරීම අතර වෙනස ඔබ දැන සිටිය යුතුය .
ඔබත් එය දැන සිටිය යුතුයි the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified
.
උදාහරණයක් වශයෙන්:
int x = 5, y = 6;
int z = x++ + y++; //it is unspecified whether x++ or y++ will be evaluated first.
මෙහි තවත් උදාහරණයක් .
දැන් ස්ටෑන්ඩර්ඩ් ඉන් §5/4
පවසයි
- 1) පෙර සහ ඊළඟ අනුක්රමික ලක්ෂ්යය අතර පරිමාණ වස්තුවකට එහි ගබඩා කළ අගය ප්රකාශනයක් ඇගයීමෙන් එකවර වෙනස් කළ යුතුය.
එයින් අදහස් කරන්නේ කුමක් ද?
අවිධිමත් ලෙස එයින් අදහස් වන්නේ අනුක්රමික ලක්ෂ්ය දෙකක් අතර විචල්යයක් එක් වරකට වඩා වෙනස් නොකළ යුතු බවයි. ප්රකාශන ප්රකාශයක, next sequence point
එය සාමාන්යයෙන් අවසන් වන අර්ධ සළකුණෙහි වන අතර previous sequence point
එය පෙර ප්රකාශයේ අවසානයේ වේ. ප්රකාශනයක අතරමැදි ද අඩංගු විය හැකිය sequence points
.
ඉහත වාක්යයෙන් පහත දැක්වෙන ප්රකාශයන් නිර්වචනය නොකළ හැසිරීමක් ඉල්ලා සිටී:
i++ * ++i; // UB, i is modified more than once btw two SPs
i = ++i; // UB, same as above
++i = 2; // UB, same as above
i = ++i + 1; // UB, same as above
++++++i; // UB, parsed as (++(++(++i)))
i = (i, ++i, ++i); // UB, there's no SP between `++i` (right most) and assignment to `i` (`i` is modified more than once btw two SPs)
නමුත් පහත දැක්වෙන ප්රකාශන කදිමයි:
i = (i, ++i, 1) + 1; // well defined (AFAIK)
i = (++i, i++, i); // well defined
int j = i;
j = (++i, i++, j*i); // well defined
- 2) තවද, පෙර වටිනාකමට ප්රවේශ විය යුත්තේ ගබඩා කළ යුතු වටිනාකම තීරණය කිරීම සඳහා පමණි.
එයින් අදහස් කරන්නේ කුමක් ද? එහි අර්ථය වන්නේ යම් වස්තුවක් සම්පූර්ණ ප්රකාශනයක් තුළ ලියා ඇත්නම්, එකම ප්රකාශනය තුළ ඇති ඕනෑම හා සියලු ප්රවේශයන් ලිවිය යුතු අගය ගණනය කිරීමට directly ජුව සම්බන්ධ විය යුතුය .
උදාහරණයක් ලෙස (LHS සහ RHS හි) i = i + 1
සියලුම ප්රවේශයන් ලිවිය යුතු අගය ගණනය කිරීමට සෘජුවම සම්බන්ධ වේ . එබැවින් එය හොඳයි.i
මෙම රීතිය නවීකරණයට පෙර ප්රවේශයන් ප්රදර්ශනය කළ හැකි අයට නීතිමය ප්රකාශනයන් effectively ලදායී ලෙස සීමා කරයි.
උදාහරණ 1:
std::printf("%d %d", i,++i); // invokes Undefined Behaviour because of Rule no 2
උදාහරණ 2:
a[i] = i++ // or a[++i] = i or a[i++] = ++i etc
i
(එක් අයෙකුගේ a[i]
) ප්රවේශයකට i හි ගබඩා කර ඇති අගයට කිසිදු සම්බන්ධයක් නැති නිසා (එය සිදු වේ i++
), එබැවින් නිර්වචනය කිරීමට හොඳ ක්රමයක් නොමැත - අපගේ අවබෝධය සඳහා හෝ සම්පාදකයාගේ - වැඩි කළ අගය ගබඩා කිරීමට පෙර හෝ පසුව ප්රවේශය සිදුවිය යුතුද යන්න. එබැවින් හැසිරීම නිර්වචනය කර නැත.
උදාහරණ 3:
int x = i + i++ ;// Similar to above
C ++ 11 සඳහා පසු විපරම් පිළිතුර මෙතැනින් .
*p++ = 4
නිර්වචනය නොකළ හැසිරීම නොවේ.*p++
ලෙස අර්ථ දැක්වේ*(p++)
.p++
ප්රතිලාභp
(පිටපතක්) සහ පෙර ලිපිනයේ ගබඩා කර ඇති වටිනාකම. එය යූබී වෙත යොමු කරන්නේ ඇයි? එය ඉතා හොඳයි.