Bug 9278

Summary: Illegal use of typedef to "void"
Product: gcc Reporter: Dave Abrahams <dave>
Component: c++Assignee: Volker Reichelt <reichelt>
Status: RESOLVED FIXED    
Severity: normal CC: bangerth, ben, fang, gcc-bugs, giovannibajo, ian, jsm28, lerdsuwa, paul_m_doc, pinskia, skunk, tbm
Priority: P3 Keywords: accepts-invalid, monitored, patch
Version: 3.2   
Target Milestone: 4.2.0   
URL: http://gcc.gnu.org/ml/gcc-patches/2005-11/msg01734.html
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2005-09-10 18:42:48

Description Dave Abrahams 2003-01-11 19:56:00 UTC
This fails to compile; I don't think it should.
Trust me, there is a use case for this sort of thing! ;-)

Release:
gcc-3.2

Environment:
cygwin

How-To-Repeat:
# include <iostream>

// metafunction always returning void
template <class T> struct voidify { typedef void type; };

template <class T> struct Y {};

struct X
{
    template <class T>
    operator Y<T> (typename voidify<T>::type) const { return Y<T>(); }
};

int main()
{
    X x();
    return 0;
}
Comment 1 Wolfgang Bangerth 2003-01-12 15:52:22 UTC
State-Changed-From-To: open->analyzed
State-Changed-Why: Confirmed. I have no clue what the standard says, but an
    indication that gcc is actually wrong may be given by the
    fact that the code actually compiles when struct voidify
    is having its template removed.
    
    W.
Comment 2 Wolfgang Bangerth 2003-01-13 13:59:57 UTC
State-Changed-From-To: analyzed->open
State-Changed-Why: Given the mail by Dave, the original code was in error, and
    the converse held. So this is what should _not_ compile, but
    does, according to him. (It does so since at least 2.95.)
    I think I have no idea myself whether this is legal or
    not, I did not even know whether one can typedef void...
    ----------------------------
    struct voidify { typedef void type; };
    
    struct X {
        operator int (voidify::type) const { return 1; }
    };
    
    X x;
    ---------------------
Comment 3 Wolfgang Bangerth 2003-01-13 16:22:50 UTC
State-Changed-From-To: open->analyzed
State-Changed-Why: The corrected report has been analyzed by now.
Comment 4 Wolfgang Bangerth 2003-01-13 17:03:34 UTC
From: Wolfgang Bangerth <bangerth@ticam.utexas.edu>
To: "Joseph S. Myers" <jsm28@cam.ac.uk>
Cc: David Abrahams <dave@boost-consulting.com>, <gcc-bugs@gcc.gnu.org>,
   <gcc-gnats@gcc.gnu.org>
Subject: Re: c++/9278: dependent type in conversion operator bug
Date: Mon, 13 Jan 2003 17:03:34 -0600 (CST)

 > >   http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_closed.html#18
 > 
 > Another obscure difference between C and C++.  In C you can use a typedef
 > to void here <http://std.dkuug.dk/JTC1/SC22/WG14/www/docs/dr_157.html>.
 
 Thanks for pointing this out. This makes it very clear that the code is 
 illegal and should not compile.
 
 Indeed a very obscure feature. (Although, I must admit that, I desperately 
 needed something like that not too long ago and had to invent various 
 template metaprogramming hoops to work around...)
 
 Regards
   Wolfgang
 
 -------------------------------------------------------------------------
 Wolfgang Bangerth             email:            bangerth@ticam.utexas.edu
                               www: http://www.ticam.utexas.edu/~bangerth/
 
 

Comment 5 Wolfgang Bangerth 2003-01-13 18:27:36 UTC
From: Wolfgang Bangerth <bangerth@ticam.utexas.edu>
To: David Abrahams <dave@boost-consulting.com>
Cc: "Joseph S. Myers" <jsm28@cam.ac.uk>, <gcc-bugs@gcc.gnu.org>,
   <gcc-gnats@gcc.gnu.org>
Subject: Re: c++/9278: dependent type in conversion operator bug
Date: Mon, 13 Jan 2003 18:27:36 -0600 (CST)

 > > Indeed a very obscure feature. (Although, I must admit that, I desperately 
 > > needed something like that not too long ago and had to invent various 
 > > template metaprogramming hoops to work around...)
 > 
 > I needed exactly that yesterday, which is why it came up ;-)
 > Using SFINAE to rule out certain conversions was my game, but it
 > didn't fly :(
 
 SFINAE???
 
 In my case, I wanted to make things more uniform in Functor classes: when 
 you call a function, it either returns a value, or void. So this does not
 go together
   RETTYPE ret_val = function(args)
 if RETTYPE==void. What an annoying difference, and how convenient would it 
 be if there were "void variables", i.e. objects to which you can assign 
 the result of a void expression :-)
 
 Some template trickery and specilization can get one around this, however.
 
 W.
 
 -------------------------------------------------------------------------
 Wolfgang Bangerth             email:            bangerth@ticam.utexas.edu
                               www: http://www.ticam.utexas.edu/~bangerth/
 
 

Comment 6 Dave Abrahams 2003-01-13 19:11:46 UTC
From: David Abrahams <dave@boost-consulting.com>
To: bangerth@dealii.org
Cc: gcc-bugs@gcc.gnu.org,  gcc-prs@gcc.gnu.org,  nobody@gcc.gnu.org,
	  gcc-gnats@gcc.gnu.org
Subject: Re: c++/9278: Illegal use of typedef to "void"
Date: Mon, 13 Jan 2003 19:11:46 -0500

 bangerth@dealii.org writes:
 
 > Old Synopsis: dependent type in conversion operator bug
 > New Synopsis: Illegal use of typedef to "void"
 >
 > State-Changed-From-To: analyzed->open
 > State-Changed-By: bangerth
 > State-Changed-When: Mon Jan 13 13:59:57 2003
 > State-Changed-Why:
 >     Given the mail by Dave, the original code was in error, and
 >     the converse held. So this is what should _not_ compile, but
 >     does, according to him. (It does so since at least 2.95.)
 >     I think I have no idea myself whether this is legal or
 >     not, I did not even know whether one can typedef void...
 
 Please insert a reference to
 http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_closed.html#18
 in the GNATs issue record.  It explains what I'm saying.
 
 >     ----------------------------
 >     struct voidify { typedef void type; };
 >     
 >     struct X {
 >         operator int (voidify::type) const { return 1; }
 >     };
 >     
 >     X x;
 >     ---------------------
 >
 > http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=9278
 >
 
 -- 
                        David Abrahams
    dave@boost-consulting.com * http://www.boost-consulting.com
 Boost support, enhancements, training, and commercial distribution
 
Comment 7 Dave Abrahams 2003-01-13 19:14:07 UTC
From: David Abrahams <dave@boost-consulting.com>
To: Wolfgang Bangerth <bangerth@ticam.utexas.edu>
Cc: "Joseph S. Myers" <jsm28@cam.ac.uk>,  <gcc-bugs@gcc.gnu.org>,
	  <gcc-gnats@gcc.gnu.org>
Subject: Re: c++/9278: dependent type in conversion operator bug
Date: Mon, 13 Jan 2003 19:14:07 -0500

 Wolfgang Bangerth <bangerth@ticam.utexas.edu> writes:
 
 >> >   http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_closed.html#18
 >> 
 >> Another obscure difference between C and C++.  In C you can use a typedef
 >> to void here <http://std.dkuug.dk/JTC1/SC22/WG14/www/docs/dr_157.html>.
 >
 > Thanks for pointing this out. This makes it very clear that the code is 
 > illegal and should not compile.
 >
 > Indeed a very obscure feature. (Although, I must admit that, I desperately 
 > needed something like that not too long ago and had to invent various 
 > template metaprogramming hoops to work around...)
 
 I needed exactly that yesterday, which is why it came up ;-)
 Using SFINAE to rule out certain conversions was my game, but it
 didn't fly :(
 
 -- 
                        David Abrahams
    dave@boost-consulting.com * http://www.boost-consulting.com
 Boost support, enhancements, training, and commercial distribution
 

Comment 8 Dave Abrahams 2003-01-13 21:25:30 UTC
From: David Abrahams <dave@boost-consulting.com>
To: Wolfgang Bangerth <bangerth@ticam.utexas.edu>
Cc: "Joseph S. Myers" <jsm28@cam.ac.uk>,  <gcc-bugs@gcc.gnu.org>,
	  <gcc-gnats@gcc.gnu.org>
Subject: Re: c++/9278: dependent type in conversion operator bug
Date: Mon, 13 Jan 2003 21:25:30 -0500

 Wolfgang Bangerth <bangerth@ticam.utexas.edu> writes:
 
 >> > Indeed a very obscure feature. (Although, I must admit that, I desperately 
 >> > needed something like that not too long ago and had to invent various 
 >> > template metaprogramming hoops to work around...)
 >> 
 >> I needed exactly that yesterday, which is why it came up ;-)
 >> Using SFINAE to rule out certain conversions was my game, but it
 >> didn't fly :(
 >
 > SFINAE???
 
 "Substitution Failure Is Not An Error"
 
 basically you can take an overload out of the overload set by causing
 an invalid type computation in one of the arguments or return type:
 
 template <bool = true, class T>
 struct enable_if { typedef T type; };
 template <class T>
 struct enable_if<false,T> {};
 
 // Define addition for all enums, but only for enums
 template <class T>
 typename enable_if<boost::is_enum<T>::value, T>::type
 operator+(T x, T y) { return T(x+y); }
 
 > In my case, I wanted to make things more uniform in Functor classes: when 
 > you call a function, it either returns a value, or void. So this does not
 > go together
 >   RETTYPE ret_val = function(args)
 > if RETTYPE==void. What an annoying difference, and how convenient would it 
 > be if there were "void variables", i.e. objects to which you can assign 
 > the result of a void expression :-)
 
 Oh.  But you are allowed to write "return function(args);" even if
 function returns void.
 
 > Some template trickery and specilization can get one around this, however.
 
 Been there, done that.
 
 -- 
                        David Abrahams
    dave@boost-consulting.com * http://www.boost-consulting.com
 Boost support, enhancements, training, and commercial distribution
 

Comment 9 Joseph S. Myers 2003-01-13 22:47:47 UTC
From: "Joseph S. Myers" <jsm28@cam.ac.uk>
To: David Abrahams <dave@boost-consulting.com>
Cc: <bangerth@dealii.org>,  <gcc-bugs@gcc.gnu.org>,  <gcc-gnats@gcc.gnu.org>
Subject: Re: c++/9278: dependent type in conversion operator bug
Date: Mon, 13 Jan 2003 22:47:47 +0000 (GMT)

 On Sun, 12 Jan 2003, David Abrahams wrote:
 
 >   http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_closed.html#18
 
 Another obscure difference between C and C++.  In C you can use a typedef
 to void here <http://std.dkuug.dk/JTC1/SC22/WG14/www/docs/dr_157.html>.
 
 -- 
 Joseph S. Myers
 jsm28@cam.ac.uk
 

Comment 10 Giovanni Bajo 2003-04-07 12:57:19 UTC
From: "Giovanni Bajo" <giovannibajo@libero.it>
To: <gcc-gnats@gcc.gnu.org>,
	<dave@boost-consulting.com>,
	<gcc-bugs@gcc.gnu.org>,
	<nobody@gcc.gnu.org>,
	<gcc-prs@gcc.gnu.org>
Cc: "Wolfgang Bangerth" <bangerth@ices.utexas.edu>
Subject: Re: c++/9278: Illegal use of typedef to "void"
Date: Mon, 7 Apr 2003 12:57:19 +0200

 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&p
 r=9278
 
 Reconfirmed for 2.95 -> 3.3 as of today (bump [date] please).
 Notice that the description of the bug is misleading: "This fails to
 compile; I don't think it should." should be "This compiles correctly, but
 it should not". Bug class is not "sw-bug" but "accept-illegal".
 
 Giovanni Bajo
Comment 11 Giovanni Bajo 2004-01-14 15:31:34 UTC
Dave,

can you prepare a small self-contained testcase which uses this feature in the 
SFINAE context? It'd be really useful to prepare a full fix for this issue. 
Comment 12 Dave Abrahams 2004-01-14 18:24:10 UTC
Subject: Re:  Illegal use of typedef to "void"

"giovannibajo at libero dot it" <gcc-bugzilla@gcc.gnu.org> writes:

> ------- Additional Comments From giovannibajo at libero dot it  2004-01-14 15:31 -------
> Dave,
>
> can you prepare a small self-contained testcase which uses this feature in the 
> SFINAE context? It'd be really useful to prepare a full fix for this issue. 

I'm not sure anymore what I had in mind when I submitted it (over a
year ago), but looking over the history of this bug, I think I've been
roundly misinterpreted.  For me, the supplied code sample has always
failed to compile:

  $ g++-3.3.1 /tmp/fu.cpp
  /tmp/fu.cpp:9: error: `X::operator Y<T>(typename voidify<T>::type)' must take
     `void'

  $ g++-2 /tmp/fu.cpp
  /tmp/fu.cpp:9: `X::operator Y<T>(typename voidify<T>::type)' must take `void'
  /tmp/fu.cpp:9: `X::operator Y<T>(typename voidify<T>::type) const' must take `void'

I might have misread the CWG issue
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_closed.html#18,
thinking it was a defect.

Comment 13 Andrew Pinski 2004-01-14 18:39:49 UTC
It was detaimed that was not a DR but GCC stills accepts invalid code:
typedef void type;
should not be able to compile.
Comment 14 Dave Abrahams 2004-01-14 19:54:28 UTC
I hope you're kidding.  That would render std::allocator<void> and all 
specializations of std::ostream_iterator illegal, not to mention most of the 
programs I've written for the past three years.
Comment 15 Andrew Pinski 2004-01-14 19:58:31 UTC
Okay, I read the core issue wrong.
But I should have said this is accepted but should not be:
typedef void type;
void f(type);
Comment 16 Dave Abrahams 2004-01-14 20:37:44 UTC
What compiler version?  I can't reproduce that behavior with any version I 
have on hand.
Comment 17 Andrew Pinski 2004-01-14 20:49:48 UTC
All I have GCC 3.4, 3.3.1, 2.95.3, 3.2.3. ICC 6.0 (only in ISO strict mode) warns about it though.
Comment 18 Volker Reichelt 2005-11-25 14:59:14 UTC
Subject: Bug 9278

Author: reichelt
Date: Fri Nov 25 14:59:09 2005
New Revision: 107508

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=107508
Log:
	PR c++/9278
	* decl.c (grokparms): Do not allow typedef-names in a '(void)'
	parmlist.

	* g++.dg/other/void1.C: New test.


Added:
    trunk/gcc/testsuite/g++.dg/other/void1.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/decl.c
    trunk/gcc/testsuite/ChangeLog

Comment 19 Volker Reichelt 2005-11-25 15:07:11 UTC
Fixed on mainline.
Comment 20 Andrew Pinski 2006-04-22 00:17:17 UTC
*** Bug 27252 has been marked as a duplicate of this bug. ***
Comment 21 Ben Hutchings 2006-04-23 23:44:25 UTC
I have submitted a defect report about the difference from C in this respect; this is now C++ core DR 577: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#577
Please could the "fix" to GCC be reverted until this issue is settled?
Comment 22 Andrew Pinski 2006-04-24 00:41:37 UTC
(In reply to comment #21)
> Please could the "fix" to GCC be reverted until this issue is settled?

Considering the orginal DR was rejected as not a defect, I doubt yours will have an effect also.
See:
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_closed.html#18

Maybe it will be but as of right now GCC 4.2.0 follows the standard and it was settled already before.
Comment 23 Andrew Pinski 2006-11-29 00:41:08 UTC
*** Bug 30012 has been marked as a duplicate of this bug. ***
Comment 24 Martin Michlmayr 2007-02-03 15:06:27 UTC
Is the following supposed to fail given that Joseph said that it's valid C code (but not valid in C++) and the header contains extern "C":

(sid)976:tbm@em64t: ~/src] cat t.h
#if defined(__cplusplus)
extern "C" {
#endif
    typedef void ALCvoid;
    void test(ALCvoid);
#if defined(__cplusplus)
}
#endif
(sid)977:tbm@em64t: ~/src] cat t.c
#include "t.h"
(sid)978:tbm@em64t: ~/src] /usr/lib/gcc-snapshot/bin/g++ -c t.c
In file included from t.c:1:
t.h:5: error: '<anonymous>' has incomplete type
t.h:5: error: invalid use of 'ALCvoid'
Comment 25 joseph@codesourcery.com 2007-02-03 15:13:50 UTC
Subject: Re:  Illegal use of typedef to "void"

On Sat, 3 Feb 2007, tbm at cyrius dot com wrote:

> Is the following supposed to fail given that Joseph said that it's valid C code
> (but not valid in C++) and the header contains extern "C":

extern "C" does not change the language rules, only linkage.  The contents 
must still be valid C++ and are interpreted according to C++ rules for 
those cases where the same code is valid C and C++ but has different 
semantics in the two languages.

Comment 26 Andrew Pinski 2007-05-24 02:56:16 UTC
*** Bug 32058 has been marked as a duplicate of this bug. ***
Comment 27 Paul Doherty 2007-05-25 13:11:41 UTC
(In reply to comment #26)
> *** Bug 32058 has been marked as a duplicate of this bug. ***

Sigh :(. The response at the October 2006 to DR 577 is enough to make any template meta-programmer bang their head against the wall in despair.

This is the language that, according to its creator as a design goal should 'trust the programmer', right?

I certainly have a formal position on this and many other similar issues that affect TMP.

This should have been at most a warning with the option to turn it off.

The Visual C++ compilers may be less fussy than gcc but at least they tend to do the sensible thing.
Comment 28 Andrew Pinski 2007-06-16 04:53:08 UTC
*** Bug 32364 has been marked as a duplicate of this bug. ***
Comment 29 Andrew Pinski 2007-08-17 23:33:38 UTC
*** Bug 33101 has been marked as a duplicate of this bug. ***