ऐसे मामले हैं जब लाइब्रेरी स्रोत उपलब्ध होता है, और इसे सामान्य रूप से परिवर्तनीय पैरामीटर का समर्थन करना होता है, लेकिन व्यवहार में ये पैरामीटर आमतौर पर स्थिरांक होते हैं।सी ++ संकलन-समय निरंतर पहचान
फिर निरंतर पैरामीटर के विशेष संचालन द्वारा चीजों को अनुकूलित करना संभव हो सकता है (उदाहरण के लिए, ढेर आवंटन के बजाय स्थैतिक सरणी का उपयोग करें), लेकिन इसके लिए यह निर्धारित करना आवश्यक है कि कुछ स्थिर है (या शायद कुछ मैक्रोज़ को परिभाषित करें, लेकिन इसके कम सुविधाजनक)।
तो यहां एक कार्य कार्यान्वयन है।
अद्यतन: भी यहाँ: http://codepad.org/ngP7Kt1V
- यह वास्तव में एक वैध C++ है?
- क्या इन मैक्रोज़ से छुटकारा पाने का कोई तरीका है? (Is_const() एक समारोह क्योंकि समारोह निर्भरता सरणी आकार अभिव्यक्ति में काम नहीं करेगा नहीं किया जा सकता;। यह भी एक टेम्पलेट नहीं किया जा सकता है कि या तो एक चर पैरामीटर को स्वीकार नहीं करेगा क्योंकि)
अद्यतन: यहां इच्छित उपयोग की तरह कुछ और अपडेट है। कंपाइलर if(N==0)
शाखा के लिए कोई कोड उत्पन्न नहीं करेगा यदि नहीं है, तो हम उसी तरह से अलग-अलग डेटा संरचनाओं पर स्विच कर सकते हैं। यकीन है कि यह सही नहीं है, लेकिन इसलिए मैंने यह प्रश्न पोस्ट किया है।
#include <stdio.h>
struct chkconst {
struct Temp { Temp(int x) {} };
static char chk2(void*) { return 0; }
static int chk2(Temp ) { return 0; }
};
#define is_const_0(X) (sizeof(chkconst::chk2(X))<sizeof(int))
#define is_const_0i(X) (sizeof(chkconst::chk2(X))>sizeof(char))
#define is_const(X) is_const_0((X)^((X)&0x7FFFFFFF))
#define const_bit(X1,bit) (is_const_0i((X1)&(1<<bit))<<bit)
#define const_nibl(X1,bit) const_bit(X1,bit) | const_bit(X1,(bit+1)) | const_bit(X1,(bit+2)) | const_bit(X1,(bit+3))
#define const_byte(X1,bit) const_nibl(X1,bit) | const_nibl(X1,(bit+4))
#define const_word(X1,bit) const_byte(X1,bit) | const_byte(X1,(bit+8))
#define const_uint(X1) const_word(X1,0) | const_word(X1,16)
#define const_switch_word(X1, X2) (is_const(X1) ? const_word(X1,0) : X2)
#define const_switch_uint(X1, X2) (is_const(X1) ? const_uint(X1) : X2)
const int X1 = 222;
const int X2 = printf("") + 333;
char Y1[ const_switch_word(X1,256) ];
char Y2[ const_switch_word(X2,256) ];
template< int N >
void test(int N1) {
char _buf[N>0?N:1];
char* buf = _buf;
if(N==0) {
buf = new char[N1];
}
printf("%08X %3i %3i\n", buf, N, N1);
}
#define testwrap(N) test< const_switch_word(N,0) >(N)
int main(void) {
printf("%i %i %i\n", X1, is_const(X1), sizeof(Y1));
printf("%i %i %i\n", X2, is_const(X2), sizeof(Y2));
testwrap(X1);
testwrap(X2);
}
' is_const उदाहरण (एक परिणाम के संकलन समय अपरिभाषित कर) भी शामिल है 'is_const (एक्स) के साथ काम करता | is_const (-X) 'भी है, इस प्रकार केवल' all x: x! = INT_MIN' के लिए काम कर रहा है। –
ध्यान दें कि 'आकार (int) 'और' sizeof (char) 'को अलग होने की गारंटी नहीं है (और वास्तविक जीवन प्रोसेसर हैं जहां वे समान हैं), इसलिए आपको' char [2]' जैसे कुछ का उपयोग करना चाहिए। (दूसरी ओर, मुझे हार्डकोडेड स्थिरांक दिखाई देते हैं, इसलिए मुझे लगता है कि पोर्टेबिलिटी चिंता का विषय नहीं है।) – ymett
ग्रेट कोड, अच्छा विचार (मुझे लगता है कि मूल स्रोत http://encode.ru/threads/396-C-compile-time है -constant का पता लगाने?)। मैंने is_const कोड को कुछ और पोर्टेबल (आकार के चार मुद्दों, INT_MAX प्रयुक्त) के रूप में अनुकूलित किया है, सभी संभावित इनपुट मानों को संभालने के लिए, और एक सरल गैर-जीसीसी संस्करण बनाया - http://stackoverflow.com/questions/7658060/ देखें Can-i-use-assume-hint-to-elide-a-call-if-a-edge-condition-is-known-at-compile/7658363 # 7658363 – Suma