Reputation: 48356
Usually, the preprocessor macro is used to control some code group to be compiled or not. Here is one example.
#define ENABLE 1
void testswitch(int type){
switch(type){
case 1:
std::cout << "the value is 1" << endl;
break;
case 2:
std::cout << "the value is 2" << endl;
break;
#ifdef ENABLE
case 3:
std::cout << "the value is 3" << endl;
break;
case 4:
std::cout << "the value is 4" << endl;
}
#endif
}
}
Now I want to remove all those preprocessor macros and replace them with if
condition
void testswitch(int type, bool enable){
switch(type){
case 1:
std::cout << "the value is 1" << endl;
break;
case 2:
std::cout << "the value is 2" << endl;
break;
if (enable) {
case 3:
std::cout << "the value is 3" << endl;
break;
case 4:
std::cout << "the value is 4" << endl;
}
}
}
However, the above codes doesn't have the same logic as before. No matter the variable enable
is true
or false
, the case 3
and case 4
are always enable. Those codes are test under VS2010.
Q1: Does the compiler ignore the if
condition?
To achieve my goal, I have to change those codes as following:
void testswitch(int type, bool enable){
switch(type){
case 1:
std::cout << "the value is 1" << endl;
break;
case 2:
std::cout << "the value is 2" << endl;
break;
case 3:
if (enable)
std::cout << "the value is 3" << endl;
break;
case 4:
if (enable)
std::cout << "the value is 4" << endl;
}
}
But it seems there are redundant if
in the codes. Is there any better way to do that?
Upvotes: 2
Views: 673
Reputation: 171097
The compiler does not ignore the if
condition. But you have to bear in mind that the case
labels are labels. switch
is just a more organised approach to goto
. Since goto
can jump into blocks controlled by an if
(or a loop, or any others) just fine, so can a switch
.
You could put the enable
-only cases in a separate switch:
void testswitch(int type, bool enable) {
switch(type) {
case 1:
std::cout << "the value is 1" << endl;
break;
case 2:
std::cout << "the value is 2" << endl;
break;
default:
if (enable) {
switch(type) {
case 3:
std::cout << "the value is 3" << endl;
break;
case 4:
std::cout << "the value is 4" << endl;
break;
}
}
break;
}
}
Upvotes: 2
Reputation: 212929
One other solution is to refactor this into two switch
statements, with the second one being controlled by if (enable)
:
void testswitch(int type, bool enable) {
switch(type) {
case 1:
std::cout << "the value is 1" << endl;
break;
case 2:
std::cout << "the value is 2" << endl;
break;
default:
break;
}
if (enable) {
switch(type) {
case 3:
std::cout << "the value is 3" << endl;
break;
case 4:
std::cout << "the value is 4" << endl;
break;
default:
break;
}
}
}
Upvotes: 1
Reputation: 8583
If enable
is a constant (or otherwise known at compile-time), a reasonably smart compiler (like gcc) will not generate code to check the value of enable
, but will generate no code (if it is known to be false) or generate the then-statement otherwise.
Upvotes: 0