2012-11-09 7 views
5

Spesso ho la situazione in cui ho bisogno di più costanti generate in fase di compilazione per l'utilizzo delle operazioni di spostamento dei bit e di mascheramento.Operazioni matematiche durante la preelaborazione del compilatore

ad es.

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

vorrei che tutti questi per essere generati da blockbits, tuttavia non v'è alcuna operazione di potere che può essere utilizzato nel preprocessore che io sono a conoscenza.

Qualcuno sa un modo semplice per generare questo tipo di cose in fase di compilazione?

+0

"tuttavia non esiste alcuna operazione di alimentazione che possa essere utilizzata nel preprocessore di cui sono a conoscenza." - Davvero? per quanto riguarda il bit shift? –

+2

BTW che stiamo parlando di C++, una buona ragione per '# define' invece di costanti? – Kos

+0

Non è questo un lavoro per 'constexpr'? – DavidO

risposta

8

Si possono definire come espressioni matematiche:

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

Le parentesi sono per assicurarsi che non vi siano problemi di precedenza dell'operatore quando si utilizzano in altre espressioni.

Si potrebbe anche voler cambiare i nomi in maiuscolo come BLOCKBITS, BLOCKSIZE, ecc., Che è una convenzione di denominazione C++ per distinguere le macro dai nomi normali.

+2

+1, il preprocessore li sostituirà così com'è e il compilatore calcolerà i valori. – Kos

0

Se si desidera utilizzare const anziché # define e se si desidera creare una funzione di alimentazione generica (non solo per le potenze di 2) che calcolerà i valori in fase di esecuzione, si potrebbe anche provare a farlo con modelli come questo:

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;