Boost logo

Boost :

Subject: Re: [boost] [config] vc10 and BOOST_NO_DECLTYPE
From: Daniel Walker (daniel.j.walker_at_[hidden])
Date: 2010-04-06 21:22:34


On Tue, Apr 6, 2010 at 7:53 PM, Peter Dimov <pdimov_at_[hidden]> wrote:
> Eric Niebler wrote:
>>
>> Actually, I may have been too hasty. I notice the same behavior on recent
>> gcc builds. That is, the following program causes both vc10 and gcc in
>> std=c++0x mode to run out of heap space.
>>
>>  template<class T>
>>  struct S;
>>
>>  template<class X, class Y> struct pair {};
>>
>>  template<class T>
>>  S<T> wrap(T) { return 0; }
>>
>>  template<class T>
>>  struct S
>>  {
>>    S(int = 0) {}
>>
>>    // The following use of decltype causes the compiler to blow up:
>>    decltype(wrap(pair<T,T>())) foo() { return wrap(pair<T,T>()); }
>
> This is a CWG question. I don't think that the compilers need to instantiate
> the definition of S<pair<int,int>> from within the decltype, but it appears
> that they do, and the standard may well require them to. The other
> unevaluated context, sizeof, would instantiate because it needs the size,
> and if decltype shares the same code, it will too.

I just took a closer look at this. I ran gcc on Eric's example for 30
minutes without ICE, but it never halted. I got an error "invalid use
of incomplete type" on a more minimal example.

template<class T>
struct S;

template<class T>
S<T> wrap(T) { return 0; }

template<class T>
struct S
{
  typedef decltype(wrap(T())) type; // error
};

int main()
{
  S<int> s;
}

I believe the error is in compliance with the draft standard. N3092
7.1.6.2.4 states:

"The type denoted by decltype(e) is defined as follows: ... if e is a
function call (5.2.2) or an invocation of an overloaded operator
(parentheses around e are ignored), decltype(e) is the return type of
the statically chosen function;"

5.2.2.3 states:

"The type of the function call expression is the return type of the
statically chosen function (i.e., ignoring the virtual keyword), even
if the type of the function actually called is different. This type
shall be a complete object type, a reference type or the type void."

So, it seems the draft requires compilers to reject code taking
decltype of an incomplete type.

Daniel Walker


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk