COMPGROUPS.NET | Search | Post Question | Groups | Stream | About | Register

### Duplicated Code Woes

• Follow

```Hi.

I've heard that, and it seems like a pretty good rule, duplicated code
is bad. Duplicated code is harder to maintain -- if you update one you
better make sure you update the clones (and if you forget one --
BUG!!!!!), harder to read, etc. But in some cases, just what can you
do?

Like this little puppy I've got. It is supposed to implement
"saturation arithmetic" (i.e. where a number is "clamped" in certain
bounds, so that when it "overflows", the result is "clipped" at the
bounds.). I have two routines -- one to add, one to subtract -- but
they look kinda similar: they're the same basic structure but with
different function calls:

---

SaturationNumber<T> &operator+=(const T rhs)
{
number = max;
number = min;
else
number += rhs;

return(*this);
}

SaturationNumber<T> &operator-=(const T rhs)
{
if(DoesSubtractionExceedMax(number, rhs, max))
number = max;
else if(DoesSubtractionExceedMin(number, rhs, min))
number = min;
else
number -= rhs;

return(*this);
}

---

seems there is no easy way to merge these since the function calls are
thoroughly different.

(You may wonder: why do we need a special function
"DoesAdditionExceedMax", etc.? Why not just "if a + b > max then..."?
The answer, of course, is that a + b may Overflow, and the routine is
designed to catch that. To write the checks directly in the ifs would
be a nasty complicated conditional, and so I move that to a separate
function to keep things clear.)

So, is this "duplicated code", as in the "bad thing" I worry about,
and if so, is there any better way to do this that doesn't just add
more complexity with no clear benefit? What would you do if you were
writing those routines?

```
 0
Reply mike4ty4 (405) 6/12/2012 6:51:09 AM

```On Tuesday, June 12, 2012 8:51:09 AM UTC+2, mike3 wrote:
> Hi.
>
> I've heard that, and it seems like a pretty good rule, duplicated code
> is bad. Duplicated code is harder to maintain -- if you update one you
> better make sure you update the clones (and if you forget one --
> BUG!!!!!), harder to read, etc. But in some cases, just what can you
> do?
>
> Like this little puppy I've got. It is supposed to implement
> "saturation arithmetic" (i.e. where a number is "clamped" in certain
> bounds, so that when it "overflows", the result is "clipped" at the
> bounds.). I have two routines -- one to add, one to subtract -- but
> they look kinda similar: they're the same basic structure but with
> different function calls:
>
> ---
>
>   SaturationNumber<T> &operator+=(const T rhs)
>     {
> 	number = max;
> 	number = min;
>       else
> 	number += rhs;
>
>       return(*this);
>     }
>
>
>   SaturationNumber<T> &operator-=(const T rhs)
>     {
>       if(DoesSubtractionExceedMax(number, rhs, max))
> 	number = max;
>       else if(DoesSubtractionExceedMin(number, rhs, min))
> 	number = min;
>       else
> 	number -= rhs;
>
>       return(*this);
>     }
>
> ---
>
> seems there is no easy way to merge these since the function calls are
> thoroughly different.
>
> (You may wonder: why do we need a special function
> "DoesAdditionExceedMax", etc.? Why not just "if a + b > max then..."?
> The answer, of course, is that a + b may Overflow, and the routine is
> designed to catch that. To write the checks directly in the ifs would
> be a nasty complicated conditional, and so I move that to a separate
> function to keep things clear.)
>
> So, is this "duplicated code", as in the "bad thing" I worry about,
> and if so, is there any better way to do this that doesn't just add
> more complexity with no clear benefit? What would you do if you were
> writing those routines?

I would keep my eye on how often and how these change. If often, and in sync, then I would err towards one helper routine that does the work and parametrize moving parts.

I would not lose sleep over this detail. Duplicated code can be MUCH worse, and there's a point of diminishing return for ANYTHING.

Goran.
```
 0
Reply goran.pusic (299) 6/12/2012 9:51:01 AM

```mike3 <mike4ty4@yahoo.com> wrote:
> I've heard that, and it seems like a pretty good rule, duplicated code
> is bad. Duplicated code is harder to maintain -- if you update one you
> better make sure you update the clones (and if you forget one --
> BUG!!!!!), harder to read, etc. But in some cases, just what can you
> do?

In general that's true (and the longer the duplicated code, the worse).
However, there are situations where "unduplicating" it only makes things
worse (ie. rather than having two lean&clean functions that look almost
identical, you end up having one single function that's a mess full of
conditionals or other extraneous code, which isn't much better).

>  SaturationNumber<T> &operator+=(const T rhs)
>    {
>        number = max;
>        number = min;
>      else
>        number += rhs;
>
>      return(*this);
>    }
>
>
>  SaturationNumber<T> &operator-=(const T rhs)
>    {
>      if(DoesSubtractionExceedMax(number, rhs, max))
>        number = max;
>      else if(DoesSubtractionExceedMin(number, rhs, min))
>        number = min;
>      else
>        number -= rhs;
>
>      return(*this);
>    }

Those two functions are so short that I'd say it's not worth the effort
to try to merge them. The resulting function would most probably be almost
as long as those two functions combined and/or ridden with conditionals
or complicated template metaprogramming.
```
 0
Reply nospam270 (2875) 6/12/2012 10:00:59 AM

```I already deleted the original message so excuse me for tagging this into
the wrong part of the tree.

How about sidestepping the entire issue:

SaturationNumber<T> &operator-=(const T rhs)
{
return(operator+=(-rhs));
}

```
 0
Reply terryr999 (1) 6/12/2012 1:53:24 PM

```On Tue, 12 Jun 2012 15:53:24 +0200, "Terry Richards"

>I already deleted the original message so excuse me for tagging this into
>the wrong part of the tree.
>
>How about sidestepping the entire issue:
>
>SaturationNumber<T> &operator-=(const T rhs)
>    {
>      return(operator+=(-rhs));
>    }

Which will lead to bad results on many twos-complement machines if the
addend is the maximum negative number for the type.  Of course I'm
assuming that the OP's code handles that correctly.
```
 0
Reply robertwessel2 (1353) 6/12/2012 2:10:24 PM

```On Jun 12, 7:53=A0am, "Terry Richards" <terryr...@wanadoo.fr> wrote:
> I already deleted the original message so excuse me for tagging this into
> the wrong part of the tree.
>
> How about sidestepping the entire issue:
>
> SaturationNumber<T> &operator-=3D(const T rhs)
> =A0 =A0 {
> =A0 =A0 =A0 return(operator+=3D(-rhs));
> =A0 =A0 }

I thought of that too, but that requires the range of the
SaturationNumber
to be perfectly balanced +/- - wise, i.e. -n to +n, but that might not
be the
case. The range can be made essentially anything. And you _couldn't_
have a range like that if T =3D unsigned int, for example.
```
 0
Reply mike4ty4 (405) 6/12/2012 9:58:12 PM

```mike3 wrote:
> Hi.
>
> I've heard that, and it seems like a pretty good rule, duplicated code
> is bad. Duplicated code is harder to maintain -- if you update one you
> better make sure you update the clones (and if you forget one --
> BUG!!!!!), harder to read, etc. But in some cases, just what can you
> do?
>
> Like this little puppy I've got. It is supposed to implement
> "saturation arithmetic" (i.e. where a number is "clamped" in certain
> bounds, so that when it "overflows", the result is "clipped" at the
> bounds.). I have two routines -- one to add, one to subtract -- but
> they look kinda similar: they're the same basic structure but with
> different function calls:
>
> ---
>
>    SaturationNumber<T> &operator+=(const T rhs)
>      {
> 	number = max;
> 	number = min;
>        else
> 	number += rhs;
>
>        return(*this);
>      }
>
>
>    SaturationNumber<T> &operator-=(const T rhs)
>      {
>        if(DoesSubtractionExceedMax(number, rhs, max))
> 	number = max;
>        else if(DoesSubtractionExceedMin(number, rhs, min))
> 	number = min;
>        else
> 	number -= rhs;
>
>        return(*this);
>      }
>
> ---
>
> seems there is no easy way to merge these since the function calls are
> thoroughly different.
>
> (You may wonder: why do we need a special function
> "DoesAdditionExceedMax", etc.? Why not just "if a + b > max then..."?
> The answer, of course, is that a + b may Overflow, and the routine is
> designed to catch that. To write the checks directly in the ifs would
> be a nasty complicated conditional, and so I move that to a separate
> function to keep things clear.)
>
> So, is this "duplicated code", as in the "bad thing" I worry about,
> and if so, is there any better way to do this that doesn't just add
> more complexity with no clear benefit? What would you do if you were
> writing those routines?
>

How are your Does...() functions implemented? Do they try to calculate the
result in a register and check CPU flags by any chance? Then maybe you have

-Pavel
```
 0
Reply pauldontspamtolk (176) 6/13/2012 2:10:32 AM

```Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> wrote:
> How are your Does...() functions implemented? Do they try to calculate the
> result in a register and check CPU flags by any chance? Then maybe you have

Did you use a bullshit generator to come up with that paragraph?
```
 0
Reply nospam270 (2875) 6/13/2012 4:13:04 PM

```Juha Nieminen wrote:
> Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> wrote:
>> How are your Does...() functions implemented? Do they try to calculate the
>> result in a register and check CPU flags by any chance? Then maybe you have
>
> Did you use a bullshit generator to come up with that paragraph?
You surely used all your good manners to come up with yours.
```
 0
Reply pauldontspamtolk (176) 6/14/2012 3:52:35 AM

8 Replies
28 Views