इनलाइनिंग मैंने पहले function overloading based on whether the arguments are constexpr
के बारे में पूछा था। मैं एक मजबूत जोरदार कार्य करने के लिए उस प्रश्न के निराशाजनक उत्तर के आसपास काम करने की कोशिश कर रहा हूं। यह मोटे तौर पर मैं क्या करने की कोशिश कर रहा हूँ है:constexpr, static_assert, और
inline void smart_assert (bool condition) {
if (is_constexpr (condition))
static_assert (condition, "Error!!!");
else
assert (condition);
}
असल में, यह विचार है कि एक संकलन समय जांच हमेशा एक रन-टाइम की जांच अगर यह संकलन समय पर जांच करने के लिए संभव है की तुलना में बेहतर है। हालांकि, इनलाइनिंग और निरंतर फोल्डिंग जैसी चीजों के कारण, मैं हमेशा यह नहीं जानता कि संकलन समय जांच संभव है या नहीं। इसका मतलब है कि ऐसे मामले हो सकते हैं जहां assert (condition)
assert(false)
तक संकलित हो जाएं और कोड बस मुझे चलाने के लिए इंतजार कर रहा है और मुझे पता चलने से पहले उस पथ को निष्पादित करने में कोई त्रुटि है।
इसलिए, अगर यह जांचने का कोई तरीका है कि स्थिति एक कॉन्स्टेक्सप्रस है (इनलाइनिंग या अन्य अनुकूलन के कारण), तो संभव हो तो मैं static_assert
पर कॉल कर सकता हूं, और अन्यथा रन-टाइम पर जोर देता हूं। सौभाग्य से, जीसीसी में आंतरिक __builtin_constant_p (exp)
है, जो exp
एक कॉन्स्टेक्सर है, जो सच हो जाता है। मुझे नहीं पता कि अन्य कंपाइलर्स के पास यह आंतरिक है, लेकिन मैं उम्मीद कर रहा था कि इससे मेरी समस्या हल हो जाएगी।
#include <cassert>
#undef IS_CONSTEXPR
#if defined __GNUC__
#define IS_CONSTEXPR(exp) __builtin_constant_p (exp)
#else
#define IS_CONSTEXPR(exp) false
#endif
// TODO: Add other compilers
inline void smart_assert (bool const condition) {
static_assert (!IS_CONSTEXPR(condition) or condition, "Error!!!");
if (!IS_CONSTEXPR(condition))
assert (condition);
}
#undef IS_CONSTEXPR
static_assert
or
के शॉर्ट सर्किट व्यवहार पर निर्भर करता है: यह कोड है कि मैं के साथ आया है। यदि IS_CONSTEXPR
सत्य है, तो static_assert
का उपयोग किया जा सकता है, और स्थिति !true or condition
है, जो कि condition
के समान है। यदि IS_CONSTEXPR
गलत है, तो static_assert
का उपयोग नहीं किया जा सकता है, और स्थिति !false or condition
है, जो true
के समान है और static_assert
को अनदेखा किया गया है। यदि static_assert
चेक नहीं किया जा सकता है क्योंकि condition
कोई कॉन्स्टेक्स नहीं है, तो मैं अंतिम कोड के रूप में अपने कोड में रन-टाइम assert
जोड़ता हूं। हालांकि, यह काम नहीं करता है, not being able to use function arguments in a static_assert
, even if the arguments are constexpr
के लिए धन्यवाद।
विशेष रूप से, यह है कि अगर मैं जीसीसी के साथ संकलन करने की कोशिश क्या होता है:
// main.cpp
int main() {
smart_assert (false);
return 0;
}
g++ main.cpp -std=c++0x -O0
सब कुछ ठीक है, सामान्य रूप से संकलित करता है। अनुकूलन के साथ कोई इनलाइनिंग नहीं है, इसलिए IS_CONSTEXPR
गलत है और static_assert
अनदेखा किया गया है, इसलिए मुझे बस रन-टाइम assert
कथन (जो विफल रहता है) मिलता है। हालांकि,
[[email protected] test]$ g++ main.cpp -std=c++0x -O1
In file included from main.cpp:1:0:
smart_assert.hpp: In function ‘void smart_assert(bool)’:
smart_assert.hpp:12:3: error: non-constant condition for static assertion
smart_assert.hpp:12:3: error: ‘condition’ is not a constant expression
जैसे ही मैं किसी भी अनुकूलन पर बारी और इस प्रकार संभावित static_assert
शुरू किया जा करने की अनुमति है, यह विफल रहता है, क्योंकि मैं static_assert
में समारोह तर्कों का उपयोग नहीं कर सकते। क्या इस के आसपास काम करने का कोई तरीका है (भले ही इसका मतलब है कि मेरा खुद का static_assert
लागू करना)? मुझे लगता है कि मेरी सी ++ परियोजनाएं सैद्धांतिक रूप से एक स्मार्ट जोरदार बयान से लाभान्वित हो सकती हैं जो त्रुटियों को जितनी जल्दी हो सके पकड़ लेती है।
यह smart_assert
बनाने जैसा प्रतीत नहीं होता है जैसे फ़ंक्शन-जैसी मैक्रो सामान्य स्थिति में समस्या का समाधान करेगा। यह स्पष्ट रूप से इस सरल उदाहरण में काम करेगा, लेकिन condition
कॉल ग्राफ़ के दो स्तरों पर एक फ़ंक्शन से आ सकता है (लेकिन अभी भी संकलक के कारण constexpr
के रूप में संकलक के रूप में जाना जाता है), जो कि एक का उपयोग करने की एक ही समस्या में चलता है static_assert
में फ़ंक्शन पैरामीटर।
शुरू यह संभव है एक मैक्रो निर्धारित करता है कि एक अभिव्यक्ति एक वर्ग परिभाषा का विस्तार करने के इस तरह के एक मैक्रो की जरूरत नहीं होगी मानक C++ –
में लगातार @ JohannesSchaub-litb है कि क्या लिखने के लिए ? यह 'constexpr' फ़ंक्शन के अंदर प्रयोग योग्य नहीं होगा। – Potatoswatter
@pot इसे कक्षा परिभाषा में विस्तार करने की आवश्यकता क्यों होगी? –