Obfuscated C++

Last Month's Obfuscated C++
Last month we asked you to predict the output of this program:


#include <iostream>
using namespace std;

namespace N {
  void g(int) {
    cout << "g(int)\n";
  }
};

using N::g;

void r() {
  g('x');
}

namespace N {
  void g(char){
    cout << "g(char)\n";
  }
};

void s() {
  g('x');
}

using namespace N;

void t() {
  g('x');
}

int main(){
  r();
  s();
  t();
  return 0;
}
The answer hinges on which declarations of g are in scope at each call to g: the version that takes an int, or the (better match) version that takes a char.

Function r: The using-declaration "using N::g;" only introduces those declarations of g that are in namespace N and are in scope at that point of the using-declaration. This means that only the int version of g is introduced by the using-declaration. Therefore, r calls g(int).

Function s: While g(char) has been declared at this point, it has been declared in namespace N, and s is in the global namespace. No directives have introduced N::g(char) into the global namespace at this point. Therefore s calls g(int).

Function t: The using-directive "using namespace N;" introduces all the names of namespace N from that point onward, so both versions of g are in scope. Since g(char) is a better match than g(int), t calls g(char). So our program prints:


g(int)
g(int)
g(char)
CORRECTION Several alert readers wrote in to point out an additional error in the April puzzle, which contained the assignment


saved = new char[strlen(cp)]+1;
and the definition


char* rc = new char[strlen(saved)]+1;
Of course, the +1 needs to be part of the calculation of the array size, so the correct versions should have been:


saved = new char[strlen(cp)+1];
char* rc = new char[strlen(saved)+1];
Unfortunately, the versions as originally written compile cleanly, performing an almost certainly unintended bit of pointer arithmetic. By dumb luck, those versions even ran correctly on my machine. You may not have been so lucky!

This Month's Obfuscated C++
Here's another namespace question. What is printed by the following program?


#include <iostream>
using namespace std;
namespace N {
  void g(int) { cout << "g(int)\n"; }
};

using namespace N;

namespace N {
  void g(char){ cout << "g(char)\n"; }
};

int main(){
  g('x');
  return 0;
}

Rob Murray is Chief Technology Officer at the Irvine office of Nuforia, an object-oriented software consulting company based in Houston, TX. He has taught C++ at technical conferences since 1987 and is the author of C++ Strategies and Tactics. He was the founding editor of the C++ Report and may be contacted at [email protected].