Bug 11919 - int vs. typedef int bar/signedness of chars
Summary: int vs. typedef int bar/signedness of chars
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.4.0
: P2 normal
Target Milestone: 3.4.0
Assignee: Mark Mitchell
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-08-14 12:24 UTC by hans.utz
Modified: 2003-08-21 17:48 UTC (History)
1 user (show)

See Also:
Host: i686-pc-linux-gnu
Target: i686-pc-linux-gnu
Build:
Known to work:
Known to fail:
Last reconfirmed: 2003-08-14 14:27:29


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description hans.utz 2003-08-14 12:24:46 UTC
The following code fails to compile with 3.4 when int is substitued by a typedef
to int. 

==== 

void foo(signed char) {}

#ifdef ERROR
  typedef int bar;
  void foo(bar) {}
#else
  void foo(int) {}
#endif

int main (int, char **) {
  char c;
  foo(c);
  return 0;
}

====

g++ -DERROR 
reports:

foo.cpp: In function `int main(int, char**)':
foo.cpp:12: error: call of overloaded `foo(char&)' is ambiguous
foo.cpp:1: note: candidates are: void foo(signed char)
foo.cpp:5: note:                 void foo(bar)
Comment 1 Wolfgang Bangerth 2003-08-14 14:27:28 UTC
Indeed, how odd. The use of a typedef should really not make any difference. 
 
The reason, BTW, is that "char" is really "unsigned char", so either call to foo requires 
a conversion of the argument, either to "signed char" or to "int". If c is declared as 
"signed char", no error happens. However, the fact that the use of a typedef over the 
actual type makes a difference is definitely an error. Previous versions of gcc as well 
as icc compile this just fine. 
 
W. 
Comment 2 hans.utz 2003-08-14 15:01:41 UTC
Subject: Re:  int vs. typedef int bar/signedness of chars

bangerth at dealii dot org wrote:
> 
> The reason, BTW, is that "char" is really "unsigned char", so either
> call to foo requires a conversion of the argument, either to "signed
> char" or to "int". If c is declared as "signed char", no error happens.

Really? I thought char, signed char and unsigned char are three different types
in C++ (in contrast to int and signed). Adding an overloaded function

void foo(unsigned char) {};

to the test case doesn't help. Also g++ 2.95.3/3.2/3.4 will still resolve
foo(c) to foo(int). I checked by adding distinct output to the function bodies.

On the other hand, a similar test case can be built with short vs. unsingned
short vs. int. So it seems that a "typedef int T" isn't considered for default
type conversions. (Explicit conversion helps.)

Hans
Comment 3 Wolfgang Bangerth 2003-08-14 15:06:06 UTC
"char" is either equal to "unsigned char" or to "signed char", so there are really only 
two types. It's up to the compiler, though, to choose one of the alternatives. 
 
That's besides the point, though. The bug is really in that the typedef is not considered 
to be an equivalent for the original type. Using a typedef shouldn't change overload 
resolution, for sure. 
 
W. 
Comment 4 Nathan Sidwell 2003-08-14 15:14:21 UTC
char, signed char and unsigned char are three distinct types. [3.9.1]/1
char will have the same underlying properties as one of the other two,
but it is still a distinct type.

you are right it is a bug, the typedef should not effect overload
resolution. the char->signed char is an integral conversion, char->int is
an integral promotion (so is preferred)
Comment 5 Wolfgang Bangerth 2003-08-14 15:36:44 UTC
Ups, sorry for the char confusion. I (quite obviously) wasn't aware of the distinctness 
of the types. Thanks, Nathan, for explaining! 
W. 
Comment 6 Wolfgang Bangerth 2003-08-15 14:10:44 UTC
Possibly related to PR 11928 
Comment 7 CVS Commits 2003-08-21 17:44:24 UTC
Subject: Bug 11919

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	mmitchel@gcc.gnu.org	2003-08-21 17:44:17

Modified files:
	gcc/cp         : ChangeLog call.c decl2.c parser.c 
	gcc/testsuite  : ChangeLog 
Added files:
	gcc/testsuite/g++.dg/overload: prom1.C 
	gcc/testsuite/g++.dg/parse: dtor2.C using2.C 

Log message:
	PR c++/11551
	* parser.c (cp_parser_id_expression): Add declarator_p parameter.
	(cp_parser_primary_expression): Adjust call to
	cp_parser_id_expression.
	(cp_parser_unqualified_id): Complain about the use of
	typedef-names in a destructor declarator.
	(cp_parser_postfix_expression): Adjust call to
	cp_parser_id_expression.
	(cp_parser_type_parameter): Likewise.
	(cp_parser_template_argument): Likewise.
	(cp_parser_declarator_id): Likewise.
	
	PR c++/11919
	* call.c (standard_conversion): Use same_type_p, not pointer
	equality, to compare types.
	
	PR c++/10762
	* parser.c (cp_parser_using_declaration): Check for invalid uses
	of template-ids here...
	* decl2.c (do_class_using_decl): ... rather than here.
	
	PR c++/11919
	* g++.dg/overload/prom1.C: New test.
	
	PR c++/11551
	* g++.dg/parse/dtor2.C: New test.
	
	PR c++/10762
	* g++.dg/parse/using2.C: New test.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.3616&r2=1.3617
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/call.c.diff?cvsroot=gcc&r1=1.421&r2=1.422
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/decl2.c.diff?cvsroot=gcc&r1=1.662&r2=1.663
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/parser.c.diff?cvsroot=gcc&r1=1.102&r2=1.103
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.2987&r2=1.2988
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/overload/prom1.C.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/parse/dtor2.C.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/parse/using2.C.diff?cvsroot=gcc&r1=NONE&r2=1.1

Comment 8 Mark Mitchell 2003-08-21 17:48:28 UTC
Fixed in GCC 3.4.