Newsgroup: it.comp.lang.c++
Titolo: STATIC_CHECK

 >>>
template<bool> struct CompileTimeChecker
{
	CompileTimeChecker(...);
};
template<> struct CompileTimeChecker<false> { };
#define STATIC_CHECK(expr, msg)	\
{ \
	class ERROR_##msg {}; \
	(void)sizeof(CompileTimeChecker<(expr) != 0>((ERROR_##msg())));\
}
int main()
{
	STATIC_CHECK(true, messaggio_di_errore);
}
<<<
A me non funziona. A voi?
In modern C++ l'autore si è dimenticato di spiegare l'uso di 
(void)sizeof(). Eliminandolo non funziona quindi servirà per forzare 
l'istanziazione senza però sprecare spazio... boh...
Kiuhnm

 Kiuhnm
Nonostante la mia ammirazione per Alexandrescu questo modo di rilevare un 
errore a compile-time non mi soddisfa per due motivi:
1) Compila SOLO con il suo compilatore. Ho provato con CV 7 ed EDG.
2) La classe CompileTimeChecker viene istanziata quando STATIC_CHECK riceve 
come primo parametro true, cioe' quando tutto e' OK.
Ecco la mia versione modificata che comunque presenta il problema 2)
template<bool> struct CompileTimeChecker
{
CompileTimeChecker(...) {};
};
template<> struct CompileTimeChecker<false> { };
#define STATIC_CHECK(expr, msg) \
{ \
class ERROR_##msg {}; \
CompileTimeChecker<(expr) != 0> temp = CompileTimeChecker<(expr) != 
0>((ERROR_##msg()));\
}
int main(int argc, char* argv[])
{
  STATIC_CHECK(false, messaggio_di_errore);
}
Alcune considerazioni:
1c) (void)sizeof() dovrebbe servire per istanziare la classe 
CompileTimeChecker<false> ma penso che nulla vieti di farlo come ho fatto 
io, quella parte di codice non verra' istanziata se il compilatore genera un 
errore
2c) il costruttore della classe CompileTimeChecker<false> non ha (nella 
versione originale) nessun body quindi il linker genera un "undefined 
function"
Ogni commento e' gradito
Fabio


Mi correggo da solo. E' la mia implementazione che instanzia la classa.
Quella di Alexandrescu, se (void)sizeof() funzionasse, non instanzierebbe 
nulla e dunque il costruttore CompileTimeChecker<true> non avrebbe bisogno 
di nessun body
Fabio 


Avete provato a vedere:
a) la versione di loki su sourceforge;
b) come funziona BOOST_STATIC_ASSERT;
?
Ciao,
Nicola

 A me non funziona. A voi?
Propongo questo:
#define STATIC_CHECKER(cond, msg)	\
{	\
	struct ____________ERROR_##msg##____________ {};	\
	sizeof(____________ERROR_##msg##____________[cond]);	\
}
int main()
{
	const unsigned number = 23;
	STATIC_CHECKER(1 == number, 1_diverso_da_number);
}
Kiuhnm

Kiuhnm ha scritto:
[...]
Non ho parole. Ho provato il codice con Dev-C++ e ho scoperto che 
compila perfino
main()
{
   int ma_sei_scemo_QUESTION_MARK[0];
}
Kiuhnm


Riporto dal online-errata del libro che è all'indirizzo
http://erdani.org/errata/display.php?book_index=1&printing=8
[Many] The version of STATIC_CHECK included near the center of the page 
is invalid.  The expression sizeof(Compile­Time­Checker<(expr)>( 
ERROR_##msg())) is an invalid attempt to take the size of a function 
declaration.
 
[Author's note: Many readers have submitted this bug. The simplest 
solution is to simply add extra parens around ERROR_##msg() (solution 1 
below). The actual Loki code looks like solution 2 below:]
// solution 1
#define STATIC_CHECK(expr, msg) \
     {\
         class ERROR_##msg {}; \
         (void)sizeof(::Loki::CompileTimeChecker<\
             (expr) != 0>((ERROR_##msg())));\
     }
// solution 2
#define STATIC_CHECK(expr, msg) \
     { Loki::CompileTimeError<((expr) != 0)> \
     ERROR_##msg; \
     (void)ERROR_##msg; }
Many thanks to Greg Underwood, Carl Daniel and others who noticed the 
bug and proposed changes.]
HTH
Marco.