public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* C++11: Compile-time value checking of constructor arguments possible?
@ 2012-03-15 21:22 Zack Weinberg
  2012-03-15 21:34 ` Marc Glisse
  0 siblings, 1 reply; 3+ messages in thread
From: Zack Weinberg @ 2012-03-15 21:22 UTC (permalink / raw)
  To: gcc-help

It's a long story, but I happen to be trying my hand at writing a
"safe bit flags" class for C++11 and it would be extremely helpful to
be able to do compile-time value checks on constructor arguments.  It
seems like this should be possible via 'constexpr' constructors that
use static_assert inside the constructor body, but it doesn't work
with either g++ 4.6 or 4.7.  Here's an example:

$ cat test.cc
// intent is for K instances to be initializable only with an integer
// less than or equal to std::numeric_limits<int>::digits
#include <limits>
struct K
{
  K() = delete;
  K(const K&) = default;

  constexpr K(int s) : value(s == 0 ? 0 : 1 << (s-1))
  { static_assert(s <= std::numeric_limits<unsigned int>::digits, "overflow"); }

  const unsigned int value;
};

const K good(1);   // should compile
const K bad(999);  // should not compile

$ g++-4.6 -std=c++0x -fsyntax-only test.cc
test.cc: In constructor ‘constexpr K::K(int)’:
test.cc:10:5: error: non-constant condition for static assertion
test.cc:10:5: error: ‘s’ is not a constant expression

Same errors with g++ 4.7.  If I stick 'constexpr' on the constructor
argument as well, I get either a parse error (if 'constexpr' is before
'int') or 'error: a parameter cannot be declared "constexpr"' (if
'constexpr' is after 'int').  (Has C++11 broken the syntax invariant
that specifiers and qualifiers can go either before or after the base
type? Feh.)

Any advice?  Solutions that work with 4.6 *strongly* preferred.

zw

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: C++11: Compile-time value checking of constructor arguments possible?
  2012-03-15 21:22 C++11: Compile-time value checking of constructor arguments possible? Zack Weinberg
@ 2012-03-15 21:34 ` Marc Glisse
  2012-03-15 21:50   ` Zack Weinberg
  0 siblings, 1 reply; 3+ messages in thread
From: Marc Glisse @ 2012-03-15 21:34 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: gcc-help

On Thu, 15 Mar 2012, Zack Weinberg wrote:

> It's a long story, but I happen to be trying my hand at writing a
> "safe bit flags" class for C++11 and it would be extremely helpful to
> be able to do compile-time value checks on constructor arguments.  It
> seems like this should be possible via 'constexpr' constructors that
> use static_assert inside the constructor body, but it doesn't work
> with either g++ 4.6 or 4.7.  Here's an example:
>
> $ cat test.cc
> // intent is for K instances to be initializable only with an integer
> // less than or equal to std::numeric_limits<int>::digits
> #include <limits>
> struct K
> {
>  K() = delete;
>  K(const K&) = default;
>
>  constexpr K(int s) : value(s == 0 ? 0 : 1 << (s-1))
>  { static_assert(s <= std::numeric_limits<unsigned int>::digits, "overflow"); }
>
>  const unsigned int value;
> };
>
> const K good(1);   // should compile
> const K bad(999);  // should not compile

You'ld want constexpr on those too (if there was any chance).

> $ g++-4.6 -std=c++0x -fsyntax-only test.cc
> test.cc: In constructor ‘constexpr K::K(int)’:
> test.cc:10:5: error: non-constant condition for static assertion
> test.cc:10:5: error: ‘s’ is not a constant expression
>
> Same errors with g++ 4.7.  If I stick 'constexpr' on the constructor
> argument as well, I get either a parse error (if 'constexpr' is before
> 'int') or 'error: a parameter cannot be declared "constexpr"' (if
> 'constexpr' is after 'int').  (Has C++11 broken the syntax invariant
> that specifiers and qualifiers can go either before or after the base
> type? Feh.)

constexpr has nothing to do with const or volatile, it is closer to static 
if you want a comparison...

> Any advice?  Solutions that work with 4.6 *strongly* preferred.

Use a factory: make_K<1>() or make_K<999>() ?

-- 
Marc Glisse

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: C++11: Compile-time value checking of constructor arguments possible?
  2012-03-15 21:34 ` Marc Glisse
@ 2012-03-15 21:50   ` Zack Weinberg
  0 siblings, 0 replies; 3+ messages in thread
From: Zack Weinberg @ 2012-03-15 21:50 UTC (permalink / raw)
  To: gcc-help

On Thu, Mar 15, 2012 at 2:34 PM, Marc Glisse <marc.glisse@inria.fr> wrote:
> On Thu, 15 Mar 2012, Zack Weinberg wrote:
>> const K good(1);   // should compile
>> const K bad(999);  // should not compile
>
> You'ld want constexpr on those too (if there was any chance).

... why?

> constexpr has nothing to do with const or volatile, it is closer to static
> if you want a comparison...

I admit I don't fully understand constexpr, but this doesn't clarify
things _at all_ for me.

>> Any advice?  Solutions that work with 4.6 *strongly* preferred.
>
> Use a factory: make_K<1>() or make_K<999>() ?

This class already has too much boilerplate.  Also, it does not help
with the other situation where I need constructor value checks: an
class B whose instances do _not_ represent constants, but which should
only be initializable from K instances, B instances, or the integer
literal 0.  (I have a kludge for that involving std::nullptr_t, but I
don't like it.)

zw

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-03-15 21:50 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-03-15 21:22 C++11: Compile-time value checking of constructor arguments possible? Zack Weinberg
2012-03-15 21:34 ` Marc Glisse
2012-03-15 21:50   ` Zack Weinberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).