Enum problem with the Towers of Hanoi

  • Thread starter Thread starter John O' Meara
  • Start date Start date
Click For Summary

Discussion Overview

The discussion revolves around a C++ programming issue related to the implementation of an enum in the context of the Towers of Hanoi problem. Participants explore compiler errors, code corrections, and the implications of using specific compiler versions.

Discussion Character

  • Technical explanation
  • Debate/contested

Main Points Raised

  • One participant reports an error related to the enum values 'left', 'middle', and 'right' in an overloaded operator, suggesting confusion about enum usage.
  • Another participant points out that the issue may not be with the enum itself but rather with missing includes and namespace qualifications.
  • A participant mentions that the compiler version (g++ 4.1.2) may be problematic, indicating that it could be a buggy version that causes the ambiguity error.
  • Some participants suggest encapsulating enums in a class or namespace to avoid name collisions with global symbols.
  • There is a discussion about the overloaded stream insertion operator not being recognized correctly, with suggestions to declare it before its usage in the function.
  • One participant proposes renaming enum values to avoid conflicts with global namespace definitions, which seems to resolve the issue in a newer compiler version.
  • Another participant expresses gratitude for the assistance and acknowledges the age of the compiler being used.

Areas of Agreement / Disagreement

Participants do not reach a consensus on the root cause of the issue, with multiple competing views on whether the problem lies with the enum, the compiler version, or the code structure itself.

Contextual Notes

Limitations include the potential for name collisions in the global namespace and the specific behavior of older compiler versions, which may not adhere to modern standards.

John O' Meara
Messages
325
Reaction score
0
A C++ computer science book gives the following program. But my compiler reports an error; "void towersOfHanoi(int): error: reference to 'left' is ambiguous".
Code:
 int lineNumber;
enum pole { left, middle, right };
void towersOfHanoi(int n, pole start, pole temporary, pole destination) {
  if (n > 0) {
    towersOfHanoi(n-1, start, destination, temporary);
    lineNumber++;
    cout << lineNumber << ". Move the top from the " << start
            << " pole to the " << destination << " pole.\n";
    towersOfHanoi(n-1, temporary, start, destination);
  }
 }

 void towersOfHanoi(int d)
{
   lineNumber = 0;
   towersOfHanoi(d, left, middle, right);
}
ostream& operator<<(ostream& os, pole p)
{
  switch(p) {
     case left:        os << "left";    break;
     case middle;  os << "middle";   break;
     case right:      os << "right";     break;
   }
   return os;
 }

 int main()
 {
   towersOfHanoi(3);

   return 0;
 }
It {the book] has left me confused about enum. Can someone sort it out for me, please. Thanks in advance.
 
Physics news on Phys.org
The problems have nothing to do with the enum.

1. You aren't including <iostream>.

2. You aren't qualifying count or ostream as members of package std. (Alternative: You could use using namespace std; instead. Personally, I prefer seeing that std::stuff.

3. Your switch statement has case middle; instead of case middle: .
 
Sorry for leaving <iostream> out; I have all all of corrections included and I still get the same error and also get an ambiguous error for left, middle, and right in the overloaded operator<<(). Thanks very much.
 
What compiler are you using? Be specific (compiler and it's version).

This works fine with multiple versions of g++ and clang++:

Code:
#include <iostream>

int lineNumber;
enum pole { left, middle, right };

void towersOfHanoi (int n, pole start, pole temporary, pole destination) {
   if (n > 0) {
      towersOfHanoi(n-1, start, destination, temporary);
      lineNumber++;
      std::cout << lineNumber << ". Move the top from the " << start
                   << " pole to the " << destination << " pole.\n";
      towersOfHanoi(n-1, temporary, start, destination);
   }
}

void towersOfHanoi (int d) {
   lineNumber = 0;
   towersOfHanoi(d, left, middle, right);
}

std::ostream& operator<< (std::ostream& os, pole p) {
   switch(p) {
      case left:       os << "left";      break;
      case middle:  os << "middle";  break;
      case right:     os << "right";    break;
   }   
   return os; 
}

int main() {
   towersOfHanoi(3);

   return 0;
}
 
I am using g++ 4.1.2 (beta)on a RISC OS platform, but hasn't the gdb debugger ported, so it is an incomplete port as it stands; maybe that is what is wrong it is an incomplete port. I should report it as a bug to the porters to the RISC OS., I supose? Thanks again.
 
Here's my corrected code at codepad (http://codepad.org/rbOzNdey) and at ideone (http://ideone.com/4Az3w). This code gets your compiler error at codepad, which uses gcc 4.1.2, but not at ideone, which uses gcc 4.3.4. g++ 4.1.2 is buggy.

The problem is that the seemingly simple #include <iostream> expands into an immense amount of code. The symbols left and right are apparently defined in the global namespace in gcc 4.1.2.

I never define enums at global scope. There are just too many chances of a name collision. I always encapsulate enums in a class or a namespace. This code, http://codepad.org/H2UfSrgE, works just fine even in gcc 4.1.2.If you submit a bug report I will guarantee that they will ignore it. gcc 4.1.2 is old, old, old. So why do Linux vendors stick with it? The answer is that moving to a more modern version of gcc would make all of their code public domain. gcc 4.1.2 and gcc 4.2.1 were the last versions of gcc released under release 2 of the GNU license. Later versions of gcc use release 3. Many vendors consider that pure poison.
 
Interesting that the overloaded << doesn't want to play as intended with the enum on those, D_H. I don't think it's recognizing a distinct type, probably because the enum is just aliases for integers.
 
Joffan said:
Interesting that the overloaded << doesn't want to play as intended with the enum on those, D_H. I don't think it's recognizing a distinct type, probably because the enum is just aliases for integers.
There's no problem with the type pole, not even in the somewhat buggy g++ 4.1.2. The problem is in the enum values left and right. There is something in that big mess of code that results from #include <iostream> that pollutes the global namespace with some alternative interpretation of left and right.

To see that this is the problem, simply rename the enum values left and right to onleft and onright. This will now work just fine in g++ 4.2.1. See http://codepad.org/k3UBIyiC for a test of this modification.
 
I'm looking at the output, where the strings intended are not being produced.
 
  • #10
Joffan said:
I'm looking at the output, where the strings intended are not being produced.
Nice catch.

The problem here is the compiler doesn't know about that the overloaded stream insertion operator for type pole at the time it is compiling towersOfHanoi (int, pole, pole, pole). The solution is to define or declare operator<< ( std::ostream&, pole) before defining towersOfHanoi (int, pole, pole, pole). This code does just that: http://codepad.org/m78tumE5.
 
  • #11
Thank you D H for the trouble you went to solve my problem and the time required by you and the information/explanations given about g++ 4.1.2. I was thinking that 4.1.2 was old alright, but I didn't think that it was buggy, because it has worked fine up to now with me. Thanks again.
 

Similar threads

  • · Replies 5 ·
Replies
5
Views
3K
  • · Replies 7 ·
Replies
7
Views
3K
  • · Replies 2 ·
Replies
2
Views
6K
Replies
2
Views
8K
  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 1 ·
Replies
1
Views
3K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 6 ·
Replies
6
Views
5K