Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
| Message-ID | <ket5k7$cfg$1@dont-email.me> (permalink) |
|---|---|
| Newsgroups | comp.std.c++ |
| From | Daniel Krügler <daniel.kruegler@googlemail.com> |
| Subject | Re: detecting incomplete type |
| Organization | A noiseless patient Spider |
| References | <kepfmi$gfm$1@news.ett.com.ua> |
| Date | 2013-02-07 02:08 -0600 |
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 ]
Back to comp.std.c++ | Previous | Next — Previous in thread | Next in thread | Find similar
detecting incomplete type Balog Pal <pasa@lib.hu> - 2013-02-06 01:50 -0600 Re: detecting incomplete type Daniel Krügler <daniel.kruegler@googlemail.com> - 2013-02-07 02:08 -0600 Re: detecting incomplete type James Kuyper <jameskuyper@verizon.net> - 2013-02-07 02:31 -0600 Re: detecting incomplete type James Kanze <james.kanze@googlemail.com> - 2013-02-07 02:32 -0600
csiph-web