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

### enum and operator++

• Follow

```Dear all
I am struggling with a problem that's simple per se.
I have an enum and a prefix ++ operator:
enum Dir { North = 1, East = 2, South = 3, West = 4, Max_ = 5 };  //
clockwise

Dir operator++(Dir d)
{
Dir dd;
switch (d) {
case North:
dd = East;
break;
case East:
dd = South;
break;
case South:
dd = West;
break;
case West:  // wrap
dd = North;
break;
};

return dd;
}

void f()
{
for (Dir d = North; d < Max_; ++d)
// do something
}

The problem is: in the above loop the ++ doesn't work,
indeed the loop is infinite. If you replace // do something with
output statement, it prints 1 forever.

It is really annoying.

Regards,
-- Saeed Amrollahi
```
 0
Reply amrollahi.saeed (152) 1/20/2010 3:07:55 PM

```On 01/20/2010 11:07 PM, Saeed Amrollahi wrote:
> Dear all
> I am struggling with a problem that's simple per se.
> I have an enum and a prefix ++ operator:
> enum Dir { North = 1, East = 2, South = 3, West = 4, Max_ = 5 };  //
> clockwise
>
> Dir operator++(Dir d)
> {
>    Dir dd;
>    switch (d) {
>    case North:
>      dd = East;
>      break;
>    case East:
>      dd = South;
>      break;
>    case South:
>      dd = West;
>      break;
>    case West:  // wrap
>      dd = North;
>      break;
>    };
>
>    return dd;
> }
>
> void f()
> {
>     for (Dir d = North; d<  Max_; ++d)
----->for (Dir d = North; d<  Max_; d=++d)
>      // do something
> }
>
> The problem is: in the above loop the ++ doesn't work,
> indeed the loop is infinite. If you replace // do something with
> output statement, it prints 1 forever.
>
> It is really annoying.
>
>
> Regards,
>    -- Saeed Amrollahi

--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
```
 0

```On Jan 20, 6:21=A0pm, Yu Han <hanju...@163.com> wrote:
> On 01/20/2010 11:07 PM, Saeed Amrollahi wrote:
>
>
>
> > Dear all
> > I am struggling with a problem that's simple per se.
> > I have an enum and a prefix ++ operator:
> > enum Dir { North =3D 1, East =3D 2, South =3D 3, West =3D 4, Max_ =3D 5=
}; =A0//
> > clockwise
>
> > Dir operator++(Dir d)
> > {
> > =A0 =A0Dir dd;
> > =A0 =A0switch (d) {
> > =A0 =A0case North:
> > =A0 =A0 =A0dd =3D East;
> > =A0 =A0 =A0break;
> > =A0 =A0case East:
> > =A0 =A0 =A0dd =3D South;
> > =A0 =A0 =A0break;
> > =A0 =A0case South:
> > =A0 =A0 =A0dd =3D West;
> > =A0 =A0 =A0break;
> > =A0 =A0case West: =A0// wrap
> > =A0 =A0 =A0dd =3D North;
> > =A0 =A0 =A0break;
> > =A0 =A0};
>
> > =A0 =A0return dd;
> > }
>
> > void f()
> > {
> > =A0 =A0 for (Dir d =3D North; d< =A0Max_; ++d)
>
> ----->for (Dir d =3D North; d< =A0Max_; d=3D++d)
>
> > =A0 =A0 =A0// do something
> > }
>
> > The problem is: in the above loop the ++ doesn't work,
> > indeed the loop is infinite. If you replace // do something with
> > output statement, it prints 1 forever.
>
> > It is really annoying.
>
> > please throw a ligth.
>
> > Regards,
> > =A0 =A0-- Saeed Amrollahi
>
> --- news://freenews.netfront.net/ - complaints: n...@netfront.net ---- Hi=
de quoted text -
>
> - Show quoted text -
Yu
That's Excellent.
Why ++d isn't enough and we have to use d =3D ++d?

-- Saeed
```
 0

```In message
Saeed Amrollahi <amrollahi.saeed@gmail.com> writes
>Dear all
>I am struggling with a problem that's simple per se.
>I have an enum and a prefix ++ operator:
>enum Dir { North = 1, East = 2, South = 3, West = 4, Max_ = 5 };  //
>clockwise
>
>Dir operator++(Dir d)
>{
>  Dir dd;
>  switch (d) {
>  case North:
>    dd = East;
>    break;
>  case East:
>    dd = South;
>    break;
>  case South:
>    dd = West;
>    break;
>  case West:  // wrap
>    dd = North;
>    break;
>  };
>
>  return dd;
>}
>
>void f()
>{
>   for (Dir d = North; d < Max_; ++d)
>    // do something
>}
>
>The problem is: in the above loop the ++ doesn't work,
>indeed the loop is infinite.

The ++ works perfectly. You've defined it to cycle through North,  East,
South, West, and that's exactly what it does. No amount of
"increment"-ing will ever produce Max_.

> If you replace // do something with
>output statement, it prints 1 forever.
>
>It is really annoying.
>

Decide what you really want the increment operator to do. Should it
cycle, or just step once through the range? It can't do both, so if you
need both behaviours perhaps you should consider using named functions
--
Richard Herring
```
 0

```On Jan 20, 10:07=A0am, Saeed Amrollahi <amrollahi.sa...@gmail.com>
wrote:
> Dear all
> I am struggling with a problem that's simple per se.
> I have an enum and a prefix ++ operator:
> enum Dir { North =3D 1, East =3D 2, South =3D 3, West =3D 4, Max_ =3D 5 }=
; =A0//
> clockwise
>
> Dir operator++(Dir d)
> {
> =A0 Dir dd;
> =A0 switch (d) {
> =A0 case North:
> =A0 =A0 dd =3D East;
> =A0 =A0 break;
> =A0 case East:
> =A0 =A0 dd =3D South;
> =A0 =A0 break;
> =A0 case South:
> =A0 =A0 dd =3D West;
> =A0 =A0 break;
> =A0 case West: =A0// wrap
> =A0 =A0 dd =3D North;
> =A0 =A0 break;
> =A0 };
>
> =A0 return dd;
>
> }
>
> void f()
> {
> =A0 =A0for (Dir d =3D North; d < Max_; ++d)
> =A0 =A0 // do something
>
> }
>
> The problem is: in the above loop the ++ doesn't work,
> indeed the loop is infinite. If you replace // do something with
> output statement, it prints 1 forever.
>

Of course it's forever. Your comment says it all: West wrapped back to
North. You never hit Max.

Incidentally, you can write your operator much, much simpler than
using a case statement.

REH
```
 0

```On Jan 20, 10:34=A0am, Saeed Amrollahi <amrollahi.sa...@gmail.com>
wrote:
> On Jan 20, 6:21=A0pm, Yu Han <hanju...@163.com> wrote:
>
> > On 01/20/2010 11:07 PM, Saeed Amrollahi wrote:
>
> > > Dear all
> > > I am struggling with a problem that's simple per se.
> > > I have an enum and a prefix ++ operator:
> > > enum Dir { North =3D 1, East =3D 2, South =3D 3, West =3D 4, Max_ =3D=
5 }; =A0//
> > > clockwise
>
> > > Dir operator++(Dir d)
> > > {
> > > =A0 =A0Dir dd;
> > > =A0 =A0switch (d) {
> > > =A0 =A0case North:
> > > =A0 =A0 =A0dd =3D East;
> > > =A0 =A0 =A0break;
> > > =A0 =A0case East:
> > > =A0 =A0 =A0dd =3D South;
> > > =A0 =A0 =A0break;
> > > =A0 =A0case South:
> > > =A0 =A0 =A0dd =3D West;
> > > =A0 =A0 =A0break;
> > > =A0 =A0case West: =A0// wrap
> > > =A0 =A0 =A0dd =3D North;
> > > =A0 =A0 =A0break;
> > > =A0 =A0};
>
> > > =A0 =A0return dd;
> > > }
>
> > > void f()
> > > {
> > > =A0 =A0 for (Dir d =3D North; d< =A0Max_; ++d)
>
> > ----->for (Dir d =3D North; d< =A0Max_; d=3D++d)
>
> > > =A0 =A0 =A0// do something
> > > }
>
> > > The problem is: in the above loop the ++ doesn't work,
> > > indeed the loop is infinite. If you replace // do something with
> > > output statement, it prints 1 forever.
>
> > > It is really annoying.
>
> > > please throw a ligth.
>
> > > Regards,
> > > =A0 =A0-- Saeed Amrollahi
>
> > --- news://freenews.netfront.net/ - complaints: n...@netfront.net ---- =
Hide quoted text -
>
> > - Show quoted text -
>
> Yu
> That's Excellent.
> Why ++d isn't enough and we have to use d =3D ++d?

No, that is undefined behavior. Don't do it.

REH
```
 0

```In message <S7qsDze8KyVLFwef@baesystems.com>, Richard Herring
<junk@[127.0.0.1]> writes
>In message
>Saeed Amrollahi <amrollahi.saeed@gmail.com> writes
>>Dear all
>>I am struggling with a problem that's simple per se.
>>I have an enum and a prefix ++ operator:
>>enum Dir { North = 1, East = 2, South = 3, West = 4, Max_ = 5 };  //
>>clockwise
>>
>>Dir operator++(Dir d)

I missed the missing & here :-(

>>{
>>  Dir dd;
>>  switch (d) {
>>  case North:
>>    dd = East;
>>    break;
>>  case East:
>>    dd = South;
>>    break;
>>  case South:
>>    dd = West;
>>    break;
>>  case West:  // wrap
>>    dd = North;
>>    break;
>>  };
>>
>>  return dd;
>>}
>>
>>void f()
>>{
>>   for (Dir d = North; d < Max_; ++d)
>>    // do something
>>}
>>
>>The problem is: in the above loop the ++ doesn't work,
>>indeed the loop is infinite.
>
>The ++ works perfectly.

Except (of course)  that it takes its argument by value, not reference!

> You've defined it to cycle through North,  East, South, West, and
>that's exactly what it does.

>No amount of "increment"-ing will ever produce Max_.

That much is true.
>
>> If you replace // do something with
>>output statement, it prints 1 forever.
>>
>>It is really annoying.
>>
>
>Decide what you really want the increment operator to do. Should it
>cycle, or just step once through the range? It can't do both, so if you
>need both behaviours perhaps you should consider using named functions

--
Richard Herring
```
 0

```On Jan 20, 6:38=A0pm, REH <spamj...@stny.rr.com> wrote:
> On Jan 20, 10:07=A0am, Saeed Amrollahi <amrollahi.sa...@gmail.com>
> wrote:
>
>
>
>
>
> > Dear all
> > I am struggling with a problem that's simple per se.
> > I have an enum and a prefix ++ operator:
> > enum Dir { North =3D 1, East =3D 2, South =3D 3, West =3D 4, Max_ =3D 5=
}; =A0//
> > clockwise
>
> > Dir operator++(Dir d)
> > {
> > =A0 Dir dd;
> > =A0 switch (d) {
> > =A0 case North:
> > =A0 =A0 dd =3D East;
> > =A0 =A0 break;
> > =A0 case East:
> > =A0 =A0 dd =3D South;
> > =A0 =A0 break;
> > =A0 case South:
> > =A0 =A0 dd =3D West;
> > =A0 =A0 break;
> > =A0 case West: =A0// wrap
> > =A0 =A0 dd =3D North;
> > =A0 =A0 break;
> > =A0 };
>
> > =A0 return dd;
>
> > }
>
> > void f()
> > {
> > =A0 =A0for (Dir d =3D North; d < Max_; ++d)
> > =A0 =A0 // do something
>
> > }
>
> > The problem is: in the above loop the ++ doesn't work,
> > indeed the loop is infinite. If you replace // do something with
> > output statement, it prints 1 forever.
>
> Of course it's forever. Your comment says it all: West wrapped back to
> North. You never hit Max.
>
> Incidentally, you can write your operator much, much simpler than
> using a case statement.
>
> REH- Hide quoted text -
>
> - Show quoted text -

Hi

You are right. My code had two problems. Yu found one of them
and you found the wraping one. I removed the wrap logic in switch
statement.

BTW, why I have to write
d =3D ++d;
rather than
++d; ?

Thanks,
-- Saeed
```
 0

```On Jan 20, 6:35=A0pm, Richard Herring <junk@[127.0.0.1]> wrote:
> In message
> Saeed Amrollahi <amrollahi.sa...@gmail.com> writes
>
>
>
>
>
> >Dear all
> >I am struggling with a problem that's simple per se.
> >I have an enum and a prefix ++ operator:
> >enum Dir { North =3D 1, East =3D 2, South =3D 3, West =3D 4, Max_ =3D 5 =
}; =A0//
> >clockwise
>
> >Dir operator++(Dir d)
> >{
> > =A0Dir dd;
> > =A0switch (d) {
> > =A0case North:
> > =A0 =A0dd =3D East;
> > =A0 =A0break;
> > =A0case East:
> > =A0 =A0dd =3D South;
> > =A0 =A0break;
> > =A0case South:
> > =A0 =A0dd =3D West;
> > =A0 =A0break;
> > =A0case West: =A0// wrap
> > =A0 =A0dd =3D North;
> > =A0 =A0break;
> > =A0};
>
> > =A0return dd;
> >}
>
> >void f()
> >{
> > =A0 for (Dir d =3D North; d < Max_; ++d)
> > =A0 =A0// do something
> >}
>
> >The problem is: in the above loop the ++ doesn't work,
> >indeed the loop is infinite.
>
> The ++ works perfectly. You've defined it to cycle through North, =A0East=
,
> South, West, and that's exactly what it does. No amount of
> "increment"-ing will ever produce Max_.
>
> > If you replace // do something with
> >output statement, it prints 1 forever.
>
> >It is really annoying.
>
>
> Decide what you really want the increment operator to do. Should it
> cycle, or just step once through the range? It can't do both, so if you
> need both behaviours perhaps you should consider using named functions
> --
> Richard Herring- Hide quoted text -
>
> - Show quoted text -

Hi Richard

I removed the wrap item from my code.

Thanks,
-- Saeed
```
 0

```On Jan 20, 10:57=A0am, Saeed Amrollahi <amrollahi.sa...@gmail.com>
wrote:
> Hi
>
> You are right. My code had two problems. Yu found one of them
> and you found the wraping one. I removed the wrap logic in switch
> statement.
>
> BTW, why I have to write
> =A0 d =3D ++d;
> rather than
> =A0 ++d; ?

NO. As I said, that is undefined behavior. ++d is all you need.

REH
```
 0

```In message
Saeed Amrollahi <amrollahi.saeed@gmail.com> writes
>On Jan 20, 6:38�pm, REH <spamj...@stny.rr.com> wrote:
>> On Jan 20, 10:07�am, Saeed Amrollahi <amrollahi.sa...@gmail.com>
>> wrote:
>>
>>
>>
>>
>>
>> > Dear all
>> > I am struggling with a problem that's simple per se.
>> > I have an enum and a prefix ++ operator:
>> > enum Dir { North = 1, East = 2, South = 3, West = 4, Max_ = 5 }; �//
>> > clockwise
>>
>> > Dir operator++(Dir d)
>> > {
>> > � Dir dd;
>> > � switch (d) {
>> > � case North:
>> > � � dd = East;
>> > � � break;
>> > � case East:
>> > � � dd = South;
>> > � � break;
>> > � case South:
>> > � � dd = West;
>> > � � break;
>> > � case West: �// wrap
>> > � � dd = North;
>> > � � break;
>> > � };
>>
>> > � return dd;
>>
>> > }
>>
>> > void f()
>> > {
>> > � �for (Dir d = North; d < Max_; ++d)
>> > � � // do something
>>
>> > }
>>
>> > The problem is: in the above loop the ++ doesn't work,
>> > indeed the loop is infinite. If you replace // do something with
>> > output statement, it prints 1 forever.
>>
>> Of course it's forever. Your comment says it all: West wrapped back to
>> North. You never hit Max.
>>
>> Incidentally, you can write your operator much, much simpler than
>> using a case statement.
>>
>Hi
>
>You are right. My code had two problems. Yu found one of them
>and you found the wraping one. I removed the wrap logic in switch
>statement.
>
>BTW, why I have to write
>  d = ++d;
>rather than
>  ++d; ?

Because your operator++, despite its name, doesn't modify its argument,
and doesn't return a reference to it. That's very confusing.

You should probably have started by writing
Dir & operator++(Dir & d)
{
// code to "increment" d
return d;
}

--
Richard Herring
```
 0

```In message
<spamjunk@stny.rr.com> writes
>On Jan 20, 10:57�am, Saeed Amrollahi <amrollahi.sa...@gmail.com>
>wrote:
>> Hi
>>
>> You are right. My code had two problems. Yu found one of them
>> and you found the wraping one. I removed the wrap logic in switch
>> statement.
>>
>> BTW, why I have to write
>> � d = ++d;
>> rather than
>> � ++d; ?
>
>NO. As I said, that is undefined behavior.

Not in this case.  His operator++ is a user-defined function. Besides,
it takes its argument by value, not reference, and therefore doesn't
modify d at all ;-)

> ++d is all you need.

--
Richard Herring
```
 0

```On Jan 20, 12:19=A0pm, Richard Herring <junk@[127.0.0.1]> wrote:
> >NO. As I said, that is undefined behavior.
>
> Not in this case. =A0His operator++ is a user-defined function. Besides,
> it takes its argument by value, not reference, and therefore doesn't
> modify d at all ;-)
>
> > ++d is all you need.
>

Ah, you're correct. Good catch. But I think that's not what he
intended, going by his original code.

REH
```
 0

```On Jan 20, 10:57=A0am, Saeed Amrollahi <amrollahi.sa...@gmail.com>
wrote:
> Hi
>
> You are right. My code had two problems. Yu found one of them
> and you found the wraping one. I removed the wrap logic in switch
> statement.
>
> BTW, why I have to write
> =A0 d =3D ++d;
> rather than
> =A0 ++d; ?
>

Per your wrapping issue, and the value/reference issue noted by Mr.
Herring, I would change your operator definition to:

inline Dir& operator++(Dir& d)
{
return d =3D Dir(d + 1);
}

REH
```
 0

```On Jan 20, 3:39 pm, REH <spamj...@stny.rr.com> wrote:
> On Jan 20, 10:34 am, Saeed Amrollahi <amrollahi.sa...@gmail.com>
> wrote:

> > On Jan 20, 6:21 pm, Yu Han <hanju...@163.com> wrote:

> > > On 01/20/2010 11:07 PM, Saeed Amrollahi wrote:

> > > > I am struggling with a problem that's simple per se.
> > > > I have an enum and a prefix ++ operator:
> > > > enum Dir { North = 1, East = 2, South = 3, West = 4, Max_ = 5 };  //
> > > > clockwise

> > > > Dir operator++(Dir d)
> > > > {
> > > >    Dir dd;
> > > >    switch (d) {
> > > >    case North:
> > > >      dd = East;
> > > >      break;
> > > >    case East:
> > > >      dd = South;
> > > >      break;
> > > >    case South:
> > > >      dd = West;
> > > >      break;
> > > >    case West:  // wrap
> > > >      dd = North;
> > > >      break;
> > > >    };

> > > >    return dd;
> > > > }

> > > > void f()
> > > > {
> > > >     for (Dir d = North; d<  Max_; ++d)

> > > ----->for (Dir d = North; d<  Max_; d=++d)

> > > >      // do something
> > > > }

> > > > The problem is: in the above loop the ++ doesn't work,
> > > > indeed the loop is infinite. If you replace // do something with
> > > > output statement, it prints 1 forever.

> > That's Excellent.

No it's not.

> > Why ++d isn't enough and we have to use d = ++d?

> No, that is undefined behavior. Don't do it.

There's no undefined behavior given his definition of
operator++; in fact, it's rather difficult to get undefined
behavior with a user defined operator, because of the additional
sequence points it introduced.

There are, in fact, two problems with his code.  The first is
that his operator++ doesn't actually increment anything; it just
returns the next value.  Normally, an operator++ takes a
non-const reference as argument (or is a non-const member, but
that's not an option for enum's), and modifies its argument.
Anything else falls under the label of obfuscation, or lying to
the reader.  The second reason is that because his operator++
wraps before reaching Max_, it can never cause the value to
become >= Max_; even a correctly written operator++ will result
in an endless loop with this definition of incrementation.

--
James Kanze
```
 0

```On Jan 20, 11:41=A0pm, James Kanze <james.ka...@gmail.com> wrote:
> On Jan 20, 3:39 pm, REH <spamj...@stny.rr.com> wrote:
>
>
>
>
>
> > On Jan 20, 10:34 am, Saeed Amrollahi <amrollahi.sa...@gmail.com>
> > wrote:
> > > On Jan 20, 6:21 pm, Yu Han <hanju...@163.com> wrote:
> > > > On 01/20/2010 11:07 PM, Saeed Amrollahi wrote:
> > > > > I am struggling with a problem that's simple per se.
> > > > > I have an enum and a prefix ++ operator:
> > > > > enum Dir { North =3D 1, East =3D 2, South =3D 3, West =3D 4, Max_=
=3D 5 }; =A0//
> > > > > clockwise
> > > > > Dir operator++(Dir d)
> > > > > {
> > > > > =A0 =A0Dir dd;
> > > > > =A0 =A0switch (d) {
> > > > > =A0 =A0case North:
> > > > > =A0 =A0 =A0dd =3D East;
> > > > > =A0 =A0 =A0break;
> > > > > =A0 =A0case East:
> > > > > =A0 =A0 =A0dd =3D South;
> > > > > =A0 =A0 =A0break;
> > > > > =A0 =A0case South:
> > > > > =A0 =A0 =A0dd =3D West;
> > > > > =A0 =A0 =A0break;
> > > > > =A0 =A0case West: =A0// wrap
> > > > > =A0 =A0 =A0dd =3D North;
> > > > > =A0 =A0 =A0break;
> > > > > =A0 =A0};
> > > > > =A0 =A0return dd;
> > > > > }
> > > > > void f()
> > > > > {
> > > > > =A0 =A0 for (Dir d =3D North; d< =A0Max_; ++d)
> > > > ----->for (Dir d =3D North; d< =A0Max_; d=3D++d)
> > > > > =A0 =A0 =A0// do something
> > > > > }
> > > > > The problem is: in the above loop the ++ doesn't work,
> > > > > indeed the loop is infinite. If you replace // do something with
> > > > > output statement, it prints 1 forever.
> > > That's Excellent.
>
> No it's not.
>
> > > Why ++d isn't enough and we have to use d =3D ++d?
> > No, that is undefined behavior. Don't do it.
>
> There's no undefined behavior given his definition of
> operator++; in fact, it's rather difficult to get undefined
> behavior with a user defined operator, because of the additional
> sequence points it introduced.
>
> There are, in fact, two problems with his code. =A0The first is
> that his operator++ doesn't actually increment anything; it just
> returns the next value. =A0Normally, an operator++ takes a
> non-const reference as argument (or is a non-const member, but
> that's not an option for enum's), and modifies its argument.
> Anything else falls under the label of obfuscation, or lying to
> the reader. =A0The second reason is that because his operator++
> wraps before reaching Max_, it can never cause the value to
> become >=3D Max_; even a correctly written operator++ will result
> in an endless loop with this definition of incrementation.
>
> --
> James Kanze- Hide quoted text -
>
> - Show quoted text -

Hi James
As always, you explained the problems in my code, in a nutshell.

Everybody thanks.
-- Saeed
```
 0

```Richard Herring wrote:
> The ++ works perfectly. You've defined it to cycle through North,  East,
> South, West, and that's exactly what it does. No amount of
> "increment"-ing will ever produce Max_.

It doesn't cycle anything because it doesn't modify anything. The
implementation is *technically* non-erroneous, but logically flawed
(because it changes the meaning of an operator to something completely
different).

--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
```
 0

16 Replies
439 Views

Similiar Articles:

7/30/2012 9:46:48 AM