473,387 Members | 1,549 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Sharing code between cases

I'm wondering what the "best" is way to handle blocks of code that are
shared between two or more cases in a switch statement. Consider the
following code (assuming valid variable and function definitions,
obviously):

switch (a)
{
case 1:
if (x) return false;
y = 6;
foo();
break;

case 2:
if (x) return false;
y = 6;
bar();
break;

case 3:
foo();
break;
}

Of course, this isn't too bad, but when the first two lines turn into a
dozen, or as there are more cases that share common code, the
possibility of a change to one not being reflected to all others
increases. Generally, the solution to common code is to pull it out,
but the ways that I see of doing that here are:

1) Sequential switches
switch (a)
{
case 1:
case 2:
// shared code here
}
switch (a)
{
// unique code here
}
This might also be written like
if (a == 1 || a == 2)
{
// shared code here
}
depending on whether there were multiple different blocks of shared
code.

This method looks potentially confusing, and perhaps causes maintenance
problems.

2) Put the common code in a function that is called from each applicable
case. This would work well in some cases, but not, I think, if there
are multiple possible early return values that might be generated,
multiple variables that may be tested or affected (which now all need to
be parameters to the function), etc.

Exceptions could be a way to solve the "multiple return value" part of
the problem with this solution.
So, are there other methods I've missed that people use in this
situation? Is this perhaps an indication that I'm trying to use one
variable to control two orthogonal values (time to refactor)?

--
Greg Schmidt gr***@trawna.com
Trawna Publications http://www.trawna.com/
Jul 23 '05 #1
12 1499

"Greg Schmidt" <gr***@trawna.com> schrieb im Newsbeitrag
news:1o***************@trawna.com...
I'm wondering what the "best" is way to handle blocks of code that
are
shared between two or more cases in a switch statement. Consider
the
following code (assuming valid variable and function definitions,
obviously):

switch (a)
{
case 1:
if (x) return false;
y = 6;
foo();
break;

case 2:
if (x) return false;
y = 6;
bar();
break;

case 3:
foo();
break;
}


I do this - and I know this is considered crappy style and everyone
will flame me now - for it's fast to write:

#define DEF1 {if (x) return false; y=6;}

switch(a)
{
case 1: DEF1
foo();
break;
case 2: DEF2
bar();
break;
case 3:
foo();
break;
}

any, yes, I do this for very long blocks as well.
-Gernot


Jul 23 '05 #2
In message <1o***************@trawna.com>, Greg Schmidt
<gr***@trawna.com> writes

[switch() complications snipped]

So, are there other methods I've missed that people use in this
situation? Is this perhaps an indication that I'm trying to use one
variable to control two orthogonal values (time to refactor)?


Maybe, but don't just do the obvious and split it into two values. When
a variable is controlling complex *behaviour*, it looks like a hint that
you need to represent that behaviour by polymorphic classes. Then
instead of

switch(a)
{
/* lots of cases, lots of stuff */
}

you'll have

p->DoStuff();

--
Richard Herring
Jul 23 '05 #3

Greg Schmidt wrote:
Exceptions could be a way to solve the "multiple return value" part of the problem with this solution.


I am really surprised nobody else jumped on this one.

Exceptions are not another way to return values. Exceptions are for
exceptional situations and should not be used for flow control or
returns. That is a misuse of the feature and contains all sorts of
bugbears that love to eat lost programmers.

Jul 23 '05 #4
Greg Schmidt wrote:
I'm wondering what the "best" is way to handle blocks of code that are
shared between two or more cases in a switch statement. Consider the
following code (assuming valid variable and function definitions,
obviously):

switch (a)
{
case 1:
if (x) return false;
y = 6;
foo();
break;

case 2:
if (x) return false;
y = 6;
bar();
break;

case 3:
foo();
break;
}
...
1) Sequential switches
...


Wouldn't nested switches be more elegant than sequential ones?

switch (a)
{
case 1:
case 2:

// Common prologue
if (x) return false;
y = 6;

// Specific code (branched with 'if' or 'switch')
switch (a)
{
case 1: foo(); break;
case 2: bar(); break;
}

// Common epilogue
// ...

break;

case 3:
foo();
break;
}

--
Best regards,
Andrey Tarasevich
Jul 23 '05 #5
On Wed, 9 Feb 2005 16:54:42 +0000, Richard Herring wrote:
In message <1o***************@trawna.com>, Greg Schmidt
<gr***@trawna.com> writes

[switch() complications snipped]

So, are there other methods I've missed that people use in this
situation? Is this perhaps an indication that I'm trying to use one
variable to control two orthogonal values (time to refactor)?


Maybe, but don't just do the obvious and split it into two values. When
a variable is controlling complex *behaviour*, it looks like a hint that
you need to represent that behaviour by polymorphic classes. Then
instead of

switch(a)
{
/* lots of cases, lots of stuff */
}

you'll have

p->DoStuff();


You may be right. The library where I'm currently having this issue
(which I did most of the design for) actually makes extensive use of
polymorphism, but for some reason I had a mental block to seeing that it
might work in this case too.

--
Greg Schmidt gr***@trawna.com
Trawna Publications http://www.trawna.com/
Jul 23 '05 #6
On 9 Feb 2005 09:12:08 -0800, Noah Roberts wrote:
Greg Schmidt wrote:
Exceptions could be a way to solve the "multiple return value" part

of
the problem with this solution.


I am really surprised nobody else jumped on this one.

Exceptions are not another way to return values. Exceptions are for
exceptional situations and should not be used for flow control or
returns. That is a misuse of the feature and contains all sorts of
bugbears that love to eat lost programmers.


I'm sure if you search the archives, you'll find that this is another
one of the religious issues that comes up from time to time. I think it
depends largely on the situation. When I wrote that, I was thinking
that the multiple return values would actually tend to be codes for
different error situations, in which case an argument can be made that
"error" and "exception" can be (close to) synonymous. Certainly, using
an exception to return the result of, say, a mathematical calculation is
an abuse of the feature.

In my original, hypothetical situation, since the exception would be
thrown from the newly-created "shared code" function, which won't be
useful anywhere except very locally, the switch could be nested inside a
try block, and the catch would be right there to trap the exception and
return a "normal" result back to the caller. No need to worry about the
exception biting the unwary when its use is so limited.

--
Greg Schmidt gr***@trawna.com
Trawna Publications http://www.trawna.com/
Jul 23 '05 #7
Greg Schmidt wrote:
I'm sure if you search the archives, you'll find that this is another
one of the religious issues that comes up from time to time. I think it
depends largely on the situation. When I wrote that, I was thinking
that the multiple return values would actually tend to be codes for
different error situations, in which case an argument can be made that
"error" and "exception" can be (close to) synonymous. Certainly, using
an exception to return the result of, say, a mathematical calculation is
an abuse of the feature.
In "Thinking in C++" Eckel explains the use of exceptions as to deal
with 'exceptional' situations. In other words, the unexpected. He also
uses them to enforce function contract (or preconditions). So for
instance you wouldn't use an exception upon end of file, because that is
an expected situation, but you would if the file suddenly became
unreadable or disconnected without an eof.

I would say that is a pretty reasonable explaination.

In my original, hypothetical situation, since the exception would be
thrown from the newly-created "shared code" function, which won't be
useful anywhere except very locally, the switch could be nested inside a
try block, and the catch would be right there to trap the exception and
return a "normal" result back to the caller. No need to worry about the
exception biting the unwary when its use is so limited.


Oh I don't think so. I think it poorly advised to allow bad design to
creap into "local" functions that won't be used elsewhere for some
unforseen reason down the road. Simply because those reasons are
unforseen. When you make a function you should always assume you might
use it in ways you are not expecting to right now.
Jul 23 '05 #8
Noah Roberts wrote:
In "Thinking in C++" Eckel explains the use of exceptions as to deal
with 'exceptional' situations. In other words, the unexpected. He also
uses them to enforce function contract (or preconditions). So for
instance you wouldn't use an exception upon end of file, because that is
an expected situation, but you would if the file suddenly became


That depends. If you are reading a text file, the end of file is the normal
condition to mark the end of the text, but if you are reading for example a
file in a format that defines precisely what contains and what are the
lengths of each part, reaching end of file in the middle of a file can be
considered an excpetional condition (file is corrupt or is not in the
required format).

--
Salu2
Jul 23 '05 #9

Julián Albo wrote:
Noah Roberts wrote:
In "Thinking in C++" Eckel explains the use of exceptions as to deal with 'exceptional' situations. In other words, the unexpected. He also uses them to enforce function contract (or preconditions). So for
instance you wouldn't use an exception upon end of file, because that is an expected situation, but you would if the file suddenly became
That depends. If you are reading a text file, the end of file is the

normal condition to mark the end of the text, but if you are reading for example a file in a format that defines precisely what contains and what are the lengths of each part, reaching end of file in the middle of a file can be considered an excpetional condition (file is corrupt or is not in the
required format).


Sure. Good point.

Jul 23 '05 #10
On Thu, 10 Feb 2005 00:02:07 -0800, Noah Roberts wrote:
Greg Schmidt wrote:
I'm sure if you search the archives, you'll find that this is another
one of the religious issues that comes up from time to time. I think it
depends largely on the situation. When I wrote that, I was thinking
that the multiple return values would actually tend to be codes for
different error situations, in which case an argument can be made that
"error" and "exception" can be (close to) synonymous. Certainly, using
an exception to return the result of, say, a mathematical calculation is
an abuse of the feature.


In "Thinking in C++" Eckel explains the use of exceptions as to deal
with 'exceptional' situations. In other words, the unexpected. He also
uses them to enforce function contract (or preconditions). So for
instance you wouldn't use an exception upon end of file, because that is
an expected situation, but you would if the file suddenly became
unreadable or disconnected without an eof.


http://groups-beta.google.com/group/...c713555b51a81c
is a lengthy thread with various views on this. It seems that Herb
Sutter (who knows a thing or two about exceptions) perhaps falls closer
to my view than yours, but then I may be reading my own bias into his
posts, or he may have changed his views since then (it was over 4 years
ago).
In my original, hypothetical situation, since the exception would be
thrown from the newly-created "shared code" function, which won't be
useful anywhere except very locally, the switch could be nested inside a
try block, and the catch would be right there to trap the exception and
return a "normal" result back to the caller. No need to worry about the
exception biting the unwary when its use is so limited.


Oh I don't think so. I think it poorly advised to allow bad design to
creap into "local" functions that won't be used elsewhere for some
unforseen reason down the road. Simply because those reasons are
unforseen. When you make a function you should always assume you might
use it in ways you are not expecting to right now.


I used to agree with you, but I've since discovered that it is more
efficient to design for what you need now, and accept that the design
may need to be changed in the future, than it is to design for any
possible eventuality. If only I could get back all the time I spent
coding for possible future cases that never happened!

--
Greg Schmidt gr***@trawna.com
Trawna Publications http://www.trawna.com/
Jul 23 '05 #11

Greg Schmidt wrote:
I used to agree with you, but I've since discovered that it is more
efficient to design for what you need now, and accept that the design
may need to be changed in the future, than it is to design for any
possible eventuality. If only I could get back all the time I spent
coding for possible future cases that never happened!


You don't need to code for all possibilities, not even possible. Just
don't code assuming things that shouldn't be assumed.

Jul 23 '05 #12
Greg Schmidt wrote:
I'm wondering what the "best" is way to handle blocks of code that are
shared between two or more cases in a switch statement. Consider the
following code (assuming valid variable and function definitions,
obviously):

switch (a)
{
case 1:
if (x) return false;
y = 6;
foo();
break;

case 2:
if (x) return false;
y = 6;
bar();
break;

case 3:
foo();
break;
}

What about this:
if(x)
{
// Or switch for more
if(a!=3)
return false;

// ...

}

else
{
switch(a)
{
case 1:
{
y = 6;
foo();
break;
}

case 2:
{
y = 6;
bar();
break;
}
}
}


--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 23 '05 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

83
by: theodp | last post by:
While Mainframe and Unix users are unlikely to find it novel that Windows XP allows several family members to share a PC while enabling each to have personalized settings and folders, that's not...
5
by: geoffblanduk_nospam | last post by:
Is it valid to share namespaces across projects in C#? For example, I have a project that contains the code for a core assembly, this builds a DLL. I then have a second project in the same...
3
by: Robert W. | last post by:
I'm embarking on a project that will have both a desktop application and a Pocket PC application. It seems logical to have as much code as possible sitting in a shared project, which would be...
5
by: BPearson | last post by:
Hello I would like to have several sites share a single web.config file. To accomplish this, I would point the root of these sites to the same folder. Is there any reason why I might not want to...
11
by: Nick | last post by:
Hello, Please pardon my ignorance as this is something I should know, but I'm a little unclear. I have an MDI based app. It is setup so the user opens a file and the main child form is created....
1
by: Joe | last post by:
While I understand that Server Side Includes still work, I realize it's not the best practice for sharing code such as a common set of includes between screens. In ASP.NET I've already built...
8
by: mc | last post by:
I would like to be able to send from an ASP.NET page an email which when recieved takes the form of a "Sharing Invitation for a RSS Feed"...
27
by: Jonathan Wood | last post by:
Greetings, I'd like to write any number of classes and then use those classes from any number of .NET applications. Since we've supposedly left "DLL Hell" and ActiveX objects behind, what has...
8
by: Nathan Sokalski | last post by:
I have a form that contains a number of fields, all of which have validators. There are two submit buttons, one to update a record and one to add a record. Because the only difference in validation...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.