හොඳයි, මෙම වාක්ය ඛණ්ඩයට විකල්පයන් සඳහන් නොකිරීම ගැන මම පුදුම වෙමි. තවත් පොදු (නමුත් පැරණි) යාන්ත්රණයක් නම්, නිර්වචනය කර නොමැති ශ්රිතයක් ඇමතීම සහ ඔබේ ප්රකාශය නිවැරදි නම් ශ්රිත ඇමතුම සම්පාදනය කිරීම සඳහා ප්රශස්තකරණය මත රඳා සිටීමයි.
#define MY_COMPILETIME_ASSERT(test) \
do { \
extern void you_did_something_bad(void); \
if (!(test)) \
you_did_something_bad(void); \
} while (0)
මෙම යාන්ත්රණය ක්රියාත්මක වන අතර (ප්රශස්තිකරණය සක්රීය කර ඇති තාක් කල්) ඔබ සම්බන්ධ වන තුරු දෝෂයක් වාර්තා නොකිරීමේ අවාසිය එයට ඇත, එම අවස්ථාවේදී ඔබ_did_something_bad () ශ්රිතය සඳහා අර්ථ දැක්වීම සොයා ගැනීමට අපොහොසත් වේ. කර්නල් සංවර්ධකයින් negative ණ ප්රමාණයේ බිට්-ක්ෂේත්ර පළල සහ negative ණ ප්රමාණයේ අරා වැනි උපක්රම භාවිතා කිරීමට පටන් ගන්නේ එබැවිනි (පසුකාලීනව GCC 4.4 හි ගොඩනැගීම බිඳ දැමීම නතර විය).
සම්පාදක-කාල ප්රකාශයන්ගේ අවශ්යතාවයට අනුකම්පා කරමින්, GCC 4.3 මඟින් මෙම පැරණි සංකල්පය පුළුල් කිරීමට ඔබට ඉඩ සලසන error
ශ්රිත ගුණාංගය හඳුන්වා දුන් නමුත් ඔබ තෝරාගත් පණිවිඩයක් සමඟ සම්පාදක-කාල දෝෂයක් ජනනය කරයි - තවත් ගුප්ත "negative ණ ප්රමාණයේ අරාව නැත "දෝෂ පණිවිඩ!
#define MAKE_SURE_THIS_IS_FIVE(number) \
do { \
extern void this_isnt_five(void) __attribute__((error( \
"I asked for five and you gave me " #number))); \
if ((number) != 5) \
this_isnt_five(); \
} while (0)
ඇත්ත වශයෙන්ම, ලිනක්ස් 3.9 වන විට, අපට දැන් compiletime_assert
මෙම අංගය භාවිතා කරන මැක්රෝ නමින් හැඳින්වෙන අතර එහි ඇති බොහෝ මැක්රෝස් bug.h
ඒ අනුව යාවත්කාලීන කර ඇත. තවමත්, මෙම සාර්ව ආරම්භකය ලෙස භාවිතා කළ නොහැක. කෙසේ වෙතත්, ප්රකාශන ප්රකාශන මගින් භාවිතා කිරීම (තවත් GCC C- දිගුවක්), ඔබට හැකිය!
#define ANY_NUMBER_BUT_FIVE(number) \
({ \
typeof(number) n = (number); \
extern void this_number_is_five(void) __attribute__(( \
error("I told you not to give me a five!"))); \
if (n == 5) \
this_number_is_five(); \
n; \
})
මෙම සාර්ව එහි පරාමිතිය හරියටම එක් වරක් ඇගයීමට ලක් කරනු ඇත (එය අතුරු ආබාධ ඇති වුවහොත්) සහ සම්පාදක කාල දෝෂයක් නිර්මාණය කර "මට පහක් දෙන්න එපා යැයි මම ඔබට කීවෙමි!" ප්රකාශනය පහකට තක්සේරු කරන්නේ නම් හෝ සම්පාදක කාල නියතය නොවේ නම්.
ඉතින් අපි මෙය negative ණ ප්රමාණයේ බිට්-ක්ෂේත්ර වෙනුවට භාවිතා නොකරන්නේ ඇයි? අහෝ, ප්රකාශන ප්රකාශන භාවිතා කිරීම සඳහා දැනට බොහෝ සීමාවන් තිබේ, ඒවා නියත ආරම්භකයින් ලෙස භාවිතා කිරීම ඇතුළුව (එනුම් නියතයන්, බිට්-ක්ෂේත්ර පළල යනාදිය) ප්රකාශන ප්රකාශනය සම්පූර්ණයෙන්ම නියත වුවද එහි ස්වභාවය (එනම්, සම්පූර්ණයෙන්ම ඇගයීමට ලක් කළ හැකිය) සම්පාදනය කරන වේලාවේදී සහ වෙනත් ආකාරයකින් __builtin_constant_p()
පරීක්ෂණය සමත් වේ ). තවද, ඒවා ක්රියාකාරී ශරීරයකින් පිටත භාවිතා කළ නොහැක.
GCC විසින් මෙම අඩුපාඩු ඉතා ඉක්මණින් සංශෝධනය කරනු ඇති අතර නිරන්තර ප්රකාශන ප්රකාශන නිරන්තර ආරම්භකයින් ලෙස භාවිතා කිරීමට ඉඩ දෙනු ඇතැයි අපේක්ෂා කරමු. මෙහි ඇති අභියෝගය වන්නේ නෛතික නියත ප්රකාශනයක් යනු කුමක්ද යන්න නිර්වචනය කරන භාෂා පිරිවිතරයි. C ++ 11 මෙම වර්ගයට හෝ දෙයක් සඳහා constexpr යතුරු පදය එක් කළ නමුත් C11 හි කිසිදු ප්රතිවිරුද්ධ කොටසක් නොමැත. C11 හට ස්ථිතික ප්රකාශයන් ලැබුනද, එය මෙම ගැටලුවේ කොටසක් විසඳනු ඇත, නමුත් මෙම අඩුපාඩු සියල්ලම විසඳන්නේ නැත. එබැවින් gcc විසින් -std = gnuc99 & -std = gnuc11 හෝ එවැනි සමහරක් හරහා දිගුවක් ලෙස ලබා ගත හැකි වන අතර ප්රකාශන ප්රකාශන සහ එහි භාවිතය සඳහා ඉඩ ලබා දේ. අල්.