Enum problem with the Towers of Hanoi

  • Thread starter Thread starter John O' Meara
  • Start date Start date
AI Thread Summary
The discussion centers around a C++ program for the Towers of Hanoi that encounters a compiler error related to the enum values "left," "middle," and "right." Users identify issues such as missing the <iostream> header and incorrect syntax in the switch statement. The compiler's ambiguity arises from the global namespace pollution caused by the enum names conflicting with existing identifiers. Suggestions include renaming the enum values to avoid conflicts and ensuring the overloaded operator<< is declared before its use in the towersOfHanoi function. The conversation highlights the limitations of using an outdated compiler version, g++ 4.1.2, which may not handle enums correctly.
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 cout 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
2
Views
5K
Replies
5
Views
3K
Replies
7
Views
3K
Replies
3
Views
2K
Replies
2
Views
2K
Replies
14
Views
5K
Replies
1
Views
3K
Back
Top