Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.std.c++ > #588

Re: detecting incomplete type

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

Show all headers | View raw


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 | NextPrevious in thread | Next in thread | Find similar


Thread

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