Reputation: 4244
template <int T>
void aFunc(){}
int main()
{
int anArray[45-32];
switch(4)
{
case 4<45:
break;
}
aFunc<4*3/7&8 == 45 - 5>();
}
so this all compiles in VC++ 2005
is this standard? if so, what do the conditional operators return? 0 and 1? are there limits?
and the thing that interests me the most, can you do it in macros? defines?
Edit:
to elaborate further on the preprocessor bit:
#define STRINGAFY(n) #n
#define STRINGAFY_2(n) STRINGAFY(n)
#define SOME_RANDOM_MACRO(n) n
printf("%s", STRINGAFY(1)); //prints out "1"
printf("%s", STRINGAFY(SOME_RANDOM_MACRO(1))); //prints out "SOME_RANDOM_MACRO(1)"
printf("%s", STRINGAFY_2(SOME_RANDOM_MACRO(1))); //causes SOME_RANDOM_MACRO to be evaluated and prints out "1"
printf("%s", STRINGAFY_2(1+1)); // doesn't evaluate and print "2", prints "1+1" :(
Upvotes: 3
Views: 1138
Reputation: 299950
I think you misunderstand a bit.
The actual evaluation of constant expressions is done by the compiler, not the preprocessor. The preprocessor only evaluates macros, which is about textual substitution.
If you check out Boost.Preprocessor, you'll realize that even simple operations like addition or soustractions cannot be expressed using common expressions if you want them to be evaluated by the preprocessor.
BOOST_PP_ADD(4, 3) // expands to 7
BOOST_PP_SUB(4, 3) // expands to 1
This is done, behind the scenes, by substitions means, for example you could define it (though it would be very tiresome) like so:
#define ADD_IMPL_4_3 7
#define BOOST_PP_ADD(lhs, rhs) ADD_IMPL_##lhs##_##rhs
So this is way different from what the compiler does ;)
As for testing whether or not your compiler is able to evaluate an expression or not, just use a template.
template <int x> struct f {};
typedef f< 3*4 / 5 > super_f_type;
If it compiles, then the compiler was able to properly evaluate the expression... since otherwise it would not have been able to instantiate the template!
Note: the actual definition of BOOST_PP_ADD
is much more complicated, this is a toy example and this may not work properly > BOOST_PP_ADD(BOOST_PP_SUB(4,3),3)
.
Upvotes: 1
Reputation: 179927
To answer the last bit: there are many constants that you can use in templates, but not in macro's.
For instance, sizeof(int)
is a constant expression. But sizeof
expressions aren't evaluated in macro context. You can't write #if sizeof(int)==4
.
Also, the preprocessor can't deal with floating-point math at all.
Upvotes: 1
Reputation: 99605
This is C++ Standard 5.19:
In several places, C + + requires expressions that evaluate to an integral or enumeration constant: as array bounds (8.3.4, 5.3.4), as case expressions (6.4.2), as bit-field lengths (9.6), as enumerator initializers (7.2), as static member initializers (9.4.2), and as integral or enumeration non-type template arguments (14.3).
constant-expression: conditional-expression
An integral constant-expression can involve only literals (2.13), enumerators, const variables or static data members of integral or enumeration types initialized with constant expressions (8.5), non-type template parameters of integral or enumeration types, and sizeof expressions. Floating literals (2.13.3) can appear only if they are cast to integral or enumeration types. Only type conversions to integral or enumeration types can be used. In particular, except in sizeof expressions, functions, class objects, pointers, or references shall not be used.
Other expressions are considered constant-expressions only for the purpose of non-local static object initialization (3.6.2).
Upvotes: 1
Reputation: 18570
It doesn't look very standard to me, what I am sure of is that C++ works with bool type, so bool type has to be returned (because you code is in C++, not C, because of templates). It might be that some automatic conversion happens. As a general rule of thumb, try to avoid macros in C++.
Upvotes: 0
Reputation: 523394
is this standard?
Yes. These are called "constant expressions". (Also see 5.19 [expr.const] in the C++ standard.)
if so, what do the conditional operators return? 0 and 1? are there limits?
false
and true
, which can be implicitly converted to 0 and 1. (Of course, in your case 0 is returned because &
has lower precedence than ==
.)
can you do it in macros? defines?
I don't understand this question. Some expressions are evaluated in preprocessing time in #if
, but otherwise left untouched.
Upvotes: 7