Condensing nested switch statements

  • Thread starter Christopher Benson-Manica
  • Start date
C

Christopher Benson-Manica

On a note related to my question about logical XOR, I'm trying to
think of a non-obfuscated way to condense the following code block
(which, as usual, I did not write):

switch( int_val_1 ) {
case 0:
switch( int_val_2 ) {
case enum_val_1: return( num1 == num2 );
case enum_val_2: return( num1 <= num2 );
case enum_val_3: return( num1 >= num2 );
default: return( true );
}
case 1:
switch( int_val_2 ) {
case enum_val_1: return( num1 != num2 );
case enum_val_2: return( num1 > num2 );
case enum_val_3: return( num1 < num2 );
default: return( true );
}
default:
return true;
}

Any suggestions?
 
R

Richard Bos

Christopher Benson-Manica said:
switch( int_val_1 ) {
case 0:
switch( int_val_2 ) {
case enum_val_1: return( num1 == num2 );
case enum_val_2: return( num1 <= num2 );
case enum_val_3: return( num1 >= num2 );
default: return( true );
}
case 1:
switch( int_val_2 ) {
case enum_val_1: return( num1 != num2 );
case enum_val_2: return( num1 > num2 );
case enum_val_3: return( num1 < num2 );
default: return( true );
}
default:
return true;
}

Any suggestions?

Yes: why? This code isn't really obfuscated. Ok, the _design_ probably
isn't all that hot, with the two different control variables, but
there's little you can do about that without changing the semantics.

Richard
 
N

nrk

Christopher said:
On a note related to my question about logical XOR, I'm trying to
think of a non-obfuscated way to condense the following code block
(which, as usual, I did not write):

switch( int_val_1 ) {
case 0:
switch( int_val_2 ) {
case enum_val_1: return( num1 == num2 );
case enum_val_2: return( num1 <= num2 );
case enum_val_3: return( num1 >= num2 );
default: return( true );
}
case 1:
switch( int_val_2 ) {
case enum_val_1: return( num1 != num2 );
case enum_val_2: return( num1 > num2 );
case enum_val_3: return( num1 < num2 );
default: return( true );
}
default:
return true;
}

Any suggestions?

You can condense it, but I don't consider the following to be an improvement
(hopefully, I haven't changed the semantics either):

int ret;

if ( int_val_1 != !!int_val_1 ) return true;
switch ( int_val_2 ) {
case enum_val_1: ret = (num1 == num2); break;
case enum_val_2: ret = (num1 <= num2); break;
case enum_val_3: ret = (num1 >= num2); break;
default: return true;
}
return ret ^ int_val_1;

Less readable, less flexible, more error-prone. Wow!! If job security was a
priority, I wouldn't hesitate to incorporate this "improvement" :)

-nrk.
 
C

CBFalconer

Christopher said:
On a note related to my question about logical XOR, I'm trying to
think of a non-obfuscated way to condense the following code block
(which, as usual, I did not write):

switch( int_val_1 ) {
case 0:
switch( int_val_2 ) {
case enum_val_1: return( num1 == num2 );
case enum_val_2: return( num1 <= num2 );
case enum_val_3: return( num1 >= num2 );
default: return( true );
}
case 1:
switch( int_val_2 ) {
case enum_val_1: return( num1 != num2 );
case enum_val_2: return( num1 > num2 );
case enum_val_3: return( num1 < num2 );
default: return( true );
}
default:
return true;
}

Any suggestions?

int result;

switch (int_val_2) {
case enum_val_1: result = num1 == num2;
case enum_val_2: result = num1 <= num2;
case enum_val_3: result = num1 >= num2;
default: return true; /* sounds ridiculous */
}
if (1 == int_val1) result = !result;
else if (0 != int_val1) result = true;
/* else use_result for 0 */
return result;
 
M

Mark A. Odell

On a note related to my question about logical XOR, I'm trying to
think of a non-obfuscated way to condense the following code block
(which, as usual, I did not write):

switch( int_val_1 ) {
case 0:
switch( int_val_2 ) {
case enum_val_1: return( num1 == num2 );
case enum_val_2: return( num1 <= num2 );
case enum_val_3: return( num1 >= num2 );
default: return( true );
}
case 1:
switch( int_val_2 ) {
case enum_val_1: return( num1 != num2 );
case enum_val_2: return( num1 > num2 );
case enum_val_3: return( num1 < num2 );
default: return( true );
}
default:
return true;
}

Any suggestions?

Get rid of the default cases?

switch (int_val_1)
{

case 0:
switch (int_val_2)
{
case enum_val_1: return num1 == num2;
case enum_val_2: return num1 <= num2;
case enum_val_3: return num1 >= num2;
}
break;

case 1:
switch (int_val_2)
{
case enum_val_1: return num1 != num2;
case enum_val_2: return num1 > num2;
case enum_val_3: return num1 < num2;
}
break;
}

return true; /* factor this out */

It's not much, admittedly.
 
N

nrk

CBFalconer said:
int result;

switch (int_val_2) {
case enum_val_1: result = num1 == num2;
case enum_val_2: result = num1 <= num2;
case enum_val_3: result = num1 >= num2;
default: return true; /* sounds ridiculous */
}
if (1 == int_val1) result = !result;
else if (0 != int_val1) result = true;
/* else use_result for 0 */
return result;

Your incantations have invoked the demons that reside in fall-thru hell :)
I believe this is also known as the devil's device.

-nrk.
 
H

Horst Kraemer

On a note related to my question about logical XOR, I'm trying to
think of a non-obfuscated way to condense the following code block
(which, as usual, I did not write):

switch( int_val_1 ) {
case 0:
switch( int_val_2 ) {
case enum_val_1: return( num1 == num2 );
case enum_val_2: return( num1 <= num2 );
case enum_val_3: return( num1 >= num2 );
default: return( true );
}
case 1:
switch( int_val_2 ) {
case enum_val_1: return( num1 != num2 );
case enum_val_2: return( num1 > num2 );
case enum_val_3: return( num1 < num2 );
default: return( true );
}
default:
return true;
}

Any suggestions?

Not counting the default cases you have 6 = 2*3 distinct results. So
you will definitely need 6 distinct cases. What's wrong with the code?
 
C

CBFalconer

CBFalconer said:
int result;

switch (int_val_2) {
case enum_val_1: result = num1 == num2;
case enum_val_2: result = num1 <= num2;
case enum_val_3: result = num1 >= num2;
default: return true; /* sounds ridiculous */
}
if (1 == int_val1) result = !result;
else if (0 != int_val1) result = true;
/* else use_result for 0 */
return result;

Woops! - Each case is missing a "break;" statement.
 
A

Alexander Bartolich

begin followup to Christopher Benson-Manica:
switch( int_val_1 ) {
case 0:
switch( int_val_2 ) {
case enum_val_1: return( num1 == num2 );
case enum_val_2: return( num1 <= num2 );
case enum_val_3: return( num1 >= num2 );
default: return( true );
}
case 1:
switch( int_val_2 ) {
case enum_val_1: return( num1 != num2 );
case enum_val_2: return( num1 > num2 );
case enum_val_3: return( num1 < num2 );
default: return( true );
}
default:
return true;
}

Well, if the values of int_val_2 are contiguous then there is one
obvious solution. Replace "- 0" with the actual minimum value.

switch(int_val_1 * 3 + int_val_2 - 0)
{
case 0: return( num1 == num2 );
case 1: return( num1 <= num2 );
case 2: return( num1 >= num2 );
case 3: return( num1 != num2 );
case 4: return( num1 > num2 );
case 5: return( num1 < num2 );
default: return true;
}
 
C

Christopher Benson-Manica

Not counting the default cases you have 6 = 2*3 distinct results. So
you will definitely need 6 distinct cases. What's wrong with the code?

6 distinct results, yes, but notice that they are related. After
reading replies to my other question, I gather that something like

switch( int_val_1 ) {
case 0:
case 1:
switch( int_val_2 ) {
case enum_val_1: return( (num1 == num2) ^ int_val_1 );
case enum_val_2: return( (num1 <= num2) ^ int_val_1 );
case enum_val_3: return( (num1 >= num2) ^ int_val_1 );
}
}
return 1;

would work, at the cost of some clarity.

(Sorry for the true's - I forgot to un-C++ my code...)
 
C

Christopher Benson-Manica

CBFalconer said:
default: return true; /* sounds ridiculous */

Indeed, for which I apologize - as you might have guessed, this code
actually lives in C++ world, and I forgot to make the transistion back
to this dimension.
 
C

Christopher Benson-Manica

Richard Bos said:
Yes: why? This code isn't really obfuscated. Ok, the _design_ probably
isn't all that hot, with the two different control variables, but
there's little you can do about that without changing the semantics.

Well, the code as written isn't obfuscated, but I would like to shrink
it without turning it into a job-security device. I posted a solution
rather akin to nrk's solution in my reply to Mr. Kraemer, but I'm
afraid I could be stuck here awhile if I incorporate it into the real
code.
 
E

Eric Sosman

Christopher said:
Well, the code as written isn't obfuscated, but I would like to shrink
it without turning it into a job-security device. I posted a solution
rather akin to nrk's solution in my reply to Mr. Kraemer, but I'm
afraid I could be stuck here awhile if I incorporate it into the real
code.

<topicality degree="tenuous">

If you're interested not just in rearranging the posted
code but in restructuring more general groups of multi-level
switch constructs and/or if ladders, you might want to read
up on the technique of "decision tables" (also called "decision
matrices" or sometimes "decision trees"). I haven't seen much
written about them in recent years -- heck, in recent decades --
but there was at one time an extensive literature about how
to construct them, how to optimize them for size or for speed,
how to check for completeness and other good qualities, and
so on.

</topicality>
 
P

Peter Pichler

Christopher Benson-Manica said:
Indeed, for which I apologize - as you might have guessed, this code
actually lives in C++ world, and I forgot to make the transistion back
to this dimension.

I think CBF was refering the whole default case rather than to such a petty
crime like using true.
 
C

Christopher Benson-Manica

Peter Pichler said:
I think CBF was refering the whole default case rather than to such a petty
crime like using true.

No crime is too petty for c.l.c! ;) No, I appreciate petty nitpicks.
What, specifically, is wrong with the default case, besides the fact
that it is superfluous?
 
N

nrk

Christopher said:
No crime is too petty for c.l.c! ;) No, I appreciate petty nitpicks.
What, specifically, is wrong with the default case, besides the fact
that it is superfluous?

It's an enumeration you're switching on. default should lead to
self-destruct :) IOW, the mere thought that you would get a value that
wasn't one of the enumerated constants shouldn't even begin to speculate
about the merest possibility of crossing your mind.

-nrk.
 
C

Christopher Benson-Manica

nrk said:
It's an enumeration you're switching on. default should lead to
self-destruct :) IOW, the mere thought that you would get a value that
wasn't one of the enumerated constants shouldn't even begin to speculate
about the merest possibility of crossing your mind.

Oh wow... good call. As you might surmise, the thought hadn't
crossed my mind, and the fact that I didn't write the code is a poor
excuse for not seeing the error. Thanks for a needed heads-up.
 
R

Richard Bos

Christopher Benson-Manica said:
Well, the code as written isn't obfuscated, but I would like to shrink
it without turning it into a job-security device.

Again: why? It isn't all that long. Does it occur a couple of dozen
times in that program? If so, make it a function.

Richard
 
D

David Resnick

Christopher Benson-Manica said:
Oh wow... good call. As you might surmise, the thought hadn't
crossed my mind, and the fact that I didn't write the code is a poor
excuse for not seeing the error. Thanks for a needed heads-up.

A related solution to CBFalconer's is to split it into 2 functions.
I like his better, but YMMV. This doesn't preserve the returning
of "true" or 1 on failure to get an expected input, but...

int cmp(int int_val2, int num1, int num2)
{
switch (int_val2) {
case enum_val_1: return num1 == num2;
case enum_val_2: return num1 <= num2;
case enum_val_3: return num1 >= num2;
}
assert(0); /* Or otherwise deal with failure to be receive
an enumerated case */
}

int func1(int int_val_1, int int_val_2, int num1, int num2)
{
switch (int_val_1) {
case 0: return cmp(int_val_2, num1, num2);
case 1: return !cmp(int_val_2, num1, num2);
default: assert(0); /* or otherwise deal with failure to receive
an expected value */
}
}

-David
 
O

Old Wolf

No crime is too petty for c.l.c! ;) No, I appreciate petty nitpicks.
It's an enumeration you're switching on. default should lead to
self-destruct :) IOW, the mere thought that you would get a value that
wasn't one of the enumerated constants shouldn't even begin to speculate
about the merest possibility of crossing your mind.

Well, we all know that means it is going to happen as soon as we
stop looking :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top