Topic: detecting incomplete type
Author: Balog Pal <pasa@lib.hu>
Date: Wed, 6 Feb 2013 01:50:31 CST
Raw View
What is a standard way to tell whether a type is complete or not? In a
way usable in say static_assert?
In boost code I saw sizeof(T) used that worked fine on gcc and msvc
which make that 0. But I recently read the section on sizeof that
tells it used with incomplete type makes the program ill-formed.
So what to do then? I looked through type_traits for no help.
And a related question: why is the sizeof behavior of the mentioned
compilers not the standard one? I wondered that if we had
is_complete<T> in type_traits it would probably impose ODR violation
in a pure library solution. While sizeof would just work, and even
follow established practice.
--
[ comp.std.c++ is moderated. To submit articles, try posting with your ]
[ newsreader. If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Thu, 7 Feb 2013 02:08:27 CST
Raw View
On 2013-02-06 08:50, Balog Pal wrote:
>
> What is a standard way to tell whether a type is complete or not? In a
> way usable in say static_assert?
sizeof(T) is a good indicator.
> In boost code I saw sizeof(T) used that worked fine on gcc and msvc
> which make that 0.
The latter behaviour is non-conforming. It should be ill-formed.
> But I recently read the section on sizeof that
> tells it used with incomplete type makes the program ill-formed.
Correct, therefore it *can* be used in sfinae conditions, because
these are defined in terms of a program that would be ill-formed. But
I'm strongly advocating against this kind of usage, see below.
> So what to do then? I looked through type_traits for no help.
Testing for an incomplete type should not be done by a trait, because
this trait could easily lead to ODR violations in your program. Except
for corner-cases (such as void), only a small subset of types
*remains* incomplete for the rest of the program. This means, if two
places in your program instantiate the trait is_incomplete<T> for the
same type T but that is incomplete in one place and complete in
another, your program undergoes undefined behaviour.
As an example, consider:
template<class T>
struct is_incomplete
{
template<class U, int = sizeof(U)>
static char test(int);
template<class>
static char(&test(...))[2];
static const bool value = sizeof(test<T>(0)) == 2;
};
struct Ukn;
static_assert(is_incomplete<void>::value, "Expected incomplete type");
static_assert(is_incomplete<Ukn>::value, "Expected incomplete type");
static_assert(is_incomplete<int[]>::value, "Expected incomplete type");
static_assert(is_incomplete<Ukn[]>::value, "Expected incomplete type");
static_assert(is_incomplete<Ukn[1]>::value, "Expected incomplete type");
struct Ukn{};
static_assert(!is_incomplete<Ukn>::value, "Expected complete type");
static_assert(!is_incomplete<Ukn[1]>::value, "Expected complete type");
> And a related question: why is the sizeof behavior of the mentioned
> compilers not the standard one?
Well, compilers are buggy, so what? The standard is pretty clear on that issue:
"The sizeof operator shall not be applied to an expression that has
function or incomplete type,"
The MS compiler is simply broken in this regard.
> I wondered that if we had
> is_complete<T> in type_traits it would probably impose ODR violation
> in a pure library solution.
It certainly would, see above. And the brokenness is not restricted to
the trait itself. It would easly make user-defined templates broken
that depends on this trait.
> While sizeof would just work, and even
> follow established practice.
sizeof isn't a solution for this, unless you want to make your program
ill-formed, when the condition is not satisfied (whichever).
HTH & Greetings from Bremen,
Daniel Kr gler
--
[ comp.std.c++ is moderated. To submit articles, try posting with your ]
[ newsreader. If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: James Kuyper <jameskuyper@verizon.net>
Date: Thu, 7 Feb 2013 02:31:59 CST
Raw View
On 02/06/2013 02:50 AM, Balog Pal wrote:
>
> What is a standard way to tell whether a type is complete or not? In a
> way usable in say static_assert?
It's trivial to determine at compile time whether a type is complete by
writing code for which a diagnostic is required if the type is
incomplete. However, it sounds like you want a method that can be used
in program that compiles and executes successfully. I don't know of any
standard way to do that.
...
> So what to do then? I looked through type_traits for no help.
A few of the type_traits don't require that the type they are
instantiated for be complete (all of the ones in table 48, plus
is_const, is_volatile, is_signed, and is_unsigned), but offhand I can't
come up with any construct that has standard-defined behavior for an
incomplete type which is different from that required if the type had
been complete.
--
[ comp.std.c++ is moderated. To submit articles, try posting with your ]
[ newsreader. If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: James Kanze <james.kanze@googlemail.com>
Date: Thu, 7 Feb 2013 02:32:32 CST
Raw View
On Wednesday, February 6, 2013 7:50:31 AM UTC, Balog Pal wrote:
> What is a standard way to tell whether a type is complete or not? In a
> way usable in say static_assert?
> In boost code I saw sizeof(T) used that worked fine on gcc and msvc
> which make that 0. But I recently read the section on sizeof that
> tells it used with incomplete type makes the program ill-formed.
SFINAE should help here. Something along the lines of:
template <typename T>
class Derived : public T {};
TrueType discrim( Derived<T>* );
FalseTpe discrim( ... );
and then something like `sizeof( discrim<T>( 0 ) )`. If the
type is incomplete, the instantiation of Derived<T> fails,
--
James
[ comp.std.c++ is moderated. To submit articles, try posting with your ]
[ newsreader. If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]