2012-11-09 11 views
5

Często mam sytuację, w której potrzebuję kilku stałych generowanych podczas kompilacji w celu użycia operacji przesunięcia bitowego i maskowania.Operacje matematyczne podczas wstępnego przetwarzania kompilatora

np.

#define blockbits 8 
#define blocksize 256 // could be generated from 2^blockbits 
#define blocksize 0xFF // could be generated from blocksize - 1 

Chciałbym to wszystko być generowane z blockbits jednak istnieje żadna operacja moc, która może być używana w preprocesor, że jestem świadomy.

Czy ktoś wie prosty sposób generowania tego rodzaju rzeczy w czasie kompilacji?

+0

"jednak nie ma operacji zasilania, którą można użyć w preprocesorze, którego jestem świadomy." - naprawdę? co z przesunięciem bitowym? –

+2

BTW to mówimy w C++, jakikolwiek dobry powód dla '# define' zamiast stałych? – Kos

+0

Czy to nie jest praca dla 'constexpr'? – DavidO

Odpowiedz

8

Można je zdefiniować jako wyrażeń matematycznych:

#define blockbits 8 
#define blocksize (1 << blockbits) 
#define blockXXXX (blocksize - 1) // changed from blocksize to blockXXXX, since blocksize is already taken 

Nawiasy są, aby upewnić się nie ma problemów operatorów, kiedy ich używać w innych wyrażeń.

Możesz również chcieć zmienić nazwy na wielkie litery, takie jak BLOCKBITS, BLOCKSIZE itd., Która jest konwencją nazewnictwa C++, aby odróżnić makra od normalnych nazw.

+2

+1, preprocesor zastąpi je tak jak jest, a kompilator obliczy wartości. – Kos

0

Jeśli chcesz użyć const zamiast # define i chcesz wygenerować ogólną funkcję mocy (nie tylko dla potęgi 2), która obliczy wartości w czasie wykonywania, możesz również spróbować zrobić to za pomocą takich szablonów:

template<int num, int pow> struct temp_pow 
{ 
    static const unsigned int result=temp_pow<num, pow-1>::result*num; 
}; 

template<int num> struct temp_pow<num, 1> 
{ 
    static const unsigned int result=num; 
}; 

const int BLOCKBITS = 8; 
const int BLOCKSIZE = temp_pow<2,BLOCKBITS>::result; // could be generated from 2^BLOCKBITS 
const int BLOCKSIZE_1 = BLOCKSIZE-1; 
Powiązane problemy