Есть случаи, когда источник библиотеки доступен, и он должен поддерживать переменные параметры в целом, но на практике эти параметры обычно являются константами.
Тогда может быть возможно оптимизировать вещи с помощью специальной обработкипостоянных параметров (например, использовать статические массивы вместо распределения кучи), но для этого необходимо сначала определить, является ли что-то постоянным (или, возможно, определить некоторые макросы, но это менее удобно).
Так вотрабочая реализация.
Обновление: также здесь: http://codepad.org/ngP7Kt1V
- Действительно ли это допустимый C ++?
- Есть ли способ избавиться от этих макросов?(is_const () не может быть функцией, потому что зависимость функции не будет работать в выражении размера массива; также он не может быть шаблоном, потому что он также не будет принимать переменный параметр.)
Обновление: Вот обновление с чем-то вроде использования по назначению.Компилятор не будет генерировать никакого кода для ветви if(N==0)
, если N
не равен 0. Точно так же мы можем переключиться на совершенно разные структуры данных, если захотим.Конечно, это не идеально, но вот почему я написал этот вопрос.
#include <stdio.h></p>
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 );
}