[gnu.g++.help] decl order affects ovld match?

lk@MCC.COM (Larry Ketcham) (01/30/91)

On g++ 1.37.2-beta, I've run into a case where declaration order 
determines which variant of an overloaded operator is selected as
a match.  However, this is not what I expected.  According to 
page 319 of the ARM:

	"The effects of overloading are independent of the
	order of function declarations."

In the program below, operator<< is overloaded for the class
local_streams.  Two variants of operator<< are declared:
one for an argument of type int, and one for an argument of
type char.  When operator<< is used with an actual argument
of type short, the compiler will sometimes select the int 
version and sometimes char, depending upon the order of the
overloaded operator declarations.

In the program below, defining the macro BAD will reverse the 
declaration order of the two overloaded functions.  I expect
the short to be promoted to int, but when BAD is defined, the
short is converted to char.  Why?

To get the correct result, compile the program as follows:

	g++ prom.cc -o prom

To make the program fail, compile it as follows:

	g++ prom.cc -o prom -DBAD

Is this a g++ bug?

----------------------------------------------
Larry Ketcham           lk@mcc.com
Experimental Systems
MCC			Austin, Texas


----------------prom.cc-----------------------
#include <stdio.h>
#include <string.h>
#include <builtin.h>
/*
  The compiler converts short to char (instead of promoting short to int),
  if operator<<(int) is declared before operator<<(char).
*/
class local_streams
  {
    char buffer[80];
  public:
#ifdef BAD
    local_streams& local_streams::operator << (int);
    local_streams& local_streams::operator << (char);
#else
    local_streams& local_streams::operator << (char);
    local_streams& local_streams::operator << (int);
#endif
  };

local_streams& local_streams::operator << (char c)
  {
    printf ("local_streams::operator<<(char)\n");
    strcat (buffer, &c);
    return *this;
  }

local_streams& local_streams::operator << (int i)
  {
    printf ("local_streams::operator<<(int)\n");
    strcat (buffer, itoa(i));
    return *this;
  }

main ()
{
  short int num = 88;
  local_streams io;
  io << num;
  printf ("expected output: %s\n", itoa(num));
  printf ("  actual output: %s\n", (char*)&io);
  if (strcmp((char*)&io, itoa(num)))
      printf ("Test FAILED.\n");
  else
      printf ("Test was successful.\n");
}
----------------prom.cc-----------------------