Topic: What does the standard say about Loki's ConversionHelper


Author: "Giovanni Bajo" <giovannibajo@REMOVEliberoTHIS.it>
Date: Thu, 18 Apr 2002 00:15:14 GMT
Raw View
"Mark Heaps" <heapsma@lmtas.lmco.com> ha scritto nel messaggio
news:3cbdd850.75707781@news.mar.lmco.com...

> My compiler rejects the following snippet from the Loki library:

> [...]

>   enum { exists = sizeof(H::Test(H::MakeT())) == sizeof(H::Small) };

> [...]

> The last of several exchanges with the compiler vendor, resulted in
> this analysis:

>  - in the example given, the class 'Conversion' is referring to the
> class 'Private::ConversionHelper' which hasn't been instantiated. When
> a member of the latter class is looked up, none of its internal
> information is known, so the expressions in the sizeof operator are
> viewed as not having complete types.

>[...]

> So my questions are:
> What paragraphs of the standard support (or refute) that analysis?
> Is the code legal or illegal?

The code is legal.

14.7.1/1 [temp.inst]: "Unless a class template specialization has been
explicitly instanciated or explicitly specialized, the class template
specialization is implicitly instanciated when the specialization is
referenced in a context that requires a completely-defined object type or
when the completeness of the class type affects the semantics of the
problem".

The context above clearly requires a "completly-defined object type", so the
argument of the vendor, specifically "the expressions [...] are viewed as
not having complete types" does not apply: they do not have complete type
because the template has not been instanciated, but 14.7.1 mandates an
implicitly instanciation whenever a complete type is needed.

Giovanni Bajo

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Ruslan Abdikeev" <ruslan@vr1.spb.ru>
Date: Fri, 19 Apr 2002 01:05:14 GMT
Raw View
"Mark Heaps" <heapsma@lmtas.lmco.com> wrote in message news:3cbdd850.75707781@news.mar.lmco.com...
> My compiler rejects the following snippet from the Loki library:
>
[snip]
> template <class T, class U>
> struct Conversion {
>   typedef ConversionHelper<T,U> H;
>   enum { exists = sizeof(H::Test(H::MakeT())) == sizeof(H::Small) };
[snip]
> }
>
> "ConversionHelper.cpp", line 13: error: operand of sizeof may not be a
> function
>     enum { exists = sizeof(H::Test(H::MakeT())) == sizeof(H::Small) };
>
> The last of several exchanges with the compiler vendor, resulted in
> this analysis:
> --- Vendor analysis
>  ...
[snip]
>  - in the example given, the class 'Conversion' is referring to the
> class 'Private::ConversionHelper' which hasn't been instantiated. When
> a member of the latter class is looked up, none of its internal
> information is known,
>
> so the expressions in the sizeof operator are
> viewed as not having complete types.

Nope. Your vendor is wrong.
Standard explicitly says that
   "Unless a class template specialization has been explicitly instantiated
    (14.7.2) or explicitly specialized (14.7.3), the class template
    specialization is implicitly instantiated when the specialization is
    referenced in a context that requires a completely-defined
    object type or when the completeness of the class type affects
    the semantics of the program." (14.7.1/1, temp.inst)

Standard explicitly requires that
    "The sizeof operator shall not be applied to an expression that has
    function or incomplete type..." (5.3.3/1, expr.sizeof)

That is, sizeof operator is a context that requires completely-defined
object type, and standard insists that in such a context
an implementation is required to implicitly instantiate
template specialization.

As the consequence, vendor's argument
> so the expressions in the sizeof operator are
> viewed as not having complete types.
contradicts the standard.

> So my questions are:
> What paragraphs of the standard support (or refute) that analysis?
> Is the code legal or illegal?

The code in question is perfectly legal w.r.t. the standard
subclauses 14.7.1/1 [temp.inst] and 5.3.3/1 [expr.sizeof].

Hope it helps,

Sincerely,

Ruslan Abdikeev
Brainbench MVP for Visual C++
http://www.brainbench.com




---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: heapsma@lmtas.lmco.com (Mark Heaps)
Date: Wed, 17 Apr 2002 20:59:49 GMT
Raw View
My compiler rejects the following snippet from the Loki library:

template <class T, class U>
struct ConversionHelper {
  typedef char Small;
  struct Big { char dummy[2]; };
  static Small Test(U);
  static Big   Test(...);
  static T MakeT();
};

template <class T, class U>
struct Conversion {
  typedef ConversionHelper<T,U> H;
  enum { exists = sizeof(H::Test(H::MakeT())) == sizeof(H::Small) };
  enum { exists2Way = exists && Conversion<U, T>::exists };
  enum { sameType = false };
};

int main()
{
    return    Conversion<int, long>::exists +
        10 *  Conversion<int, long>::exists2Way +
        100 * Conversion<int, long>::sameType;
}

"ConversionHelper.cpp", line 13: error: operand of sizeof may not be a
function
    enum { exists = sizeof(H::Test(H::MakeT())) == sizeof(H::Small) };

The last of several exchanges with the compiler vendor, resulted in
this analysis:
--- Vendor analysis
 ...
In this case the sizeof operator indeed has an expression, but that
expression has an incomplete type. Regrettably, the compiler is not
very clear in its diagnostic messages. However, this is what's going
on.

 - when templates are involved, they are not scanned until the point
of instantiation - their tokens are only cached, and their members and
layout is not recorded into the symbol table. C++ works this way
because templates don't actually have to have code that compiles if
they are never instantiated

 - in the example given, the class 'Conversion' is referring to the
class 'Private::ConversionHelper' which hasn't been instantiated. When
a member of the latter class is looked up, none of its internal
information is known, so the expressions in the sizeof operator are
viewed as not having complete types.

So it is not that the compiler is overly strict - it is more
fundamental in the way that template instantiation should happens.
 ...
--- End of vendor analysis

So my questions are:
What paragraphs of the standard support (or refute) that analysis?
Is the code legal or illegal?
---
Mark Heaps

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]