Topic: Compile-Time Assertions


Author: Lisa Lippincott <lisa_lippincott@bigfix.com>
Date: 2000/04/26
Raw View
Dave Asebrook <news@davea.org> wonders:
> One final thought... This seems like a resonable compile-time
> assert.  A run-time assert is part of the standard.  Is there any way
> to fuse the two together?  That is, if it is known at compile-time
> then error, else defer to run-time and perform an assertion there?

You could take advantage of the wacky nature of null pointer constants:

void Fail();
inline void Assert( void *p )          { if ( !p ) Fail(); }
inline void Assert( unsigned long b )  { if ( !b ) Fail(); }

int foo();
int *bar();
bool baz();

void f()
  {
   Assert( foo() );        // Tested at run time
   Assert( bar() );        // Tested at run time
   Assert( baz() );        // Tested at run time
   Assert( true );         // Likely optimized away
   Assert( false );        // Fails at compile time
   Assert( 0 );            // Fails at compile time
   Assert( 0L );           // Fails at compile time
   Assert( 0uL );          // Fails at run time (sorry)
   Assert( 0uL != 0 );     // Fails at compile time
  }

One would, of course, have to avoid the practice of using Assert( false )
to mark unreachable places in one's code.

                                                   --Lisa Lippincott

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: David R Tribble <david@tribble.com>
Date: 2000/04/26
Raw View
Dave Asebrook wrote:
> I've been trying to come up with a good method of performing
> assertions at compile time.  The best I've come up with so far looks
> something like:
>
> template <bool>
> class CTAssert
>     {
>     private:
>         CTAssert() { }
>     };
>
> template <>
> class CTAssert<true>
>     {
>     };
>
> int main()
>     {
>     CTAssert<true>();           // Compiles without error
>     CTAssert<1 == 0>();       // Compiles with error
>     return 0;
>     }
>
> I have tried it under Microsoft Visual C++ 6, Borland C++ 5.5, and
> a couple of other compilers without any problems.  I believe this is
> legal according to the standard, but I'm not positive.  Does anyone
> see any problems with this code which might cause problems
> when ported to other compilers?  I suppose not all compilers
> support template specialization yet, so that might be a problem,
> but I couldn't come up with a solution which didn't use
> specialization...

This is similar to several schemes that have been proposed within
the last few years.  There was at least one article in the C/C++
Users Journal a few months back about just this sort of thing.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Dave Asebrook" <news@davea.org>
Date: 2000/04/21
Raw View
On Thu, 20 Apr 2000 09:14:45 CST, Gene Bushuyev <gbush@my-
deja.com> wrote:

>Here is a simple solution for you without using specialization:
>
>template<bool b> void Assert(){int a[b];}
>
>int main()
>{
>  Assert<sizeof(int)==4>(); // ok at my system
>  Assert<sizeof(int)==2>(); // must fail
>  // see 8.3.4p1
>}

Nice simple solution...  I like it, although sadly, I'm not sure I can
use it.  I ran it through some simple tests using MSVC 6, and it
looks like some bug in the Microsoft compiler is coming into play...
 (For example, when the order of the two Assert<> calls is
switched, MSVC 6 compiles the program without error.  It looks
like MSVC is only paying attention to the last Assert call?)  Other
compilers seem fine with it though.  Maybe I'll just implement
different Asserts depending on the compiler being used....

One final thought... This seems like a resonable compile-time
assert.  A run-time assert is part of the standard.  Is there any way
to fuse the two together?  That is, if it is known at compile-time
then error, else defer to run-time and perform an assertion there?

Dave Asebrook

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Dave Asebrook" <news@davea.org>
Date: 2000/04/19
Raw View
On Tue, 18 Apr 2000 06:34:48 CST, comeau@panix.com (Greg
Comeau) wrote:

>It's unclear what you mean when you say that "this is legal"...
>What is the "this" that is legal?
>
>IOWs, your program does have an error:
CTAssert<tempT>::CTAssert()
>is private, and so CTAssert<false>() should produce a diagnostic.

Sorry about the ambiguity...  I was only asking about the validity of
the template classes, not the example useage in main().  You are
correct, I expected a diagnostic there.

>If this is what you want, then ok.

That's exactly what I wanted.

>Of course, the above will only work at compile-time,
>but you seem to want that...

That was the desired usage.  The specific use was to assert at
compile time that a template parameter had a numeric_limits
specialization.

template <class T>
class fooReq
    {
    public:
        fooReq() { CTAssert<numeric_limits<T>::is_specialized>(); }
    };

template <class T>
class foo: public fooReq
    {
    public:
        someFunction()
            {
            [code which uses numeric_limits<T> goes here]
            }
    };

This would require the template type to have numeric_limits
specialized, even if foo::someFunction was never called.  I guess I
could replace the CTAssert call with a call to standard assert, but I
thought it would be beneficial if this problem could be detected at
compile-time instead of having to wait until run-time.  Although the
error messages aren't the most helpful in diagnosing the problem,
so perhaps I'll have to rethink this a bit...


Dave Asebrook

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Gene Bushuyev <gbush@my-deja.com>
Date: 2000/04/20
Raw View
In article <38FB3536.26970.108252F7@localhost>,
  "Dave Asebrook" <news@davea.org> wrote:
> I've been trying to come up with a good method of performing
> assertions at compile time.  The best I've come up with so far looks
[snip]
> but I couldn't come up with a solution which didn't use
> specialization...

Here is a simple solution for you without using specialization:

template<bool b> void Assert(){int a[b];}

int main()
{
  Assert<sizeof(int)==4>(); // ok at my system
  Assert<sizeof(int)==2>(); // must fail
  // see 8.3.4p1
}
--
-------------------------------------
Gene Bushuyev


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Dave Asebrook" <news@davea.org>
Date: 2000/04/18
Raw View
I've been trying to come up with a good method of performing
assertions at compile time.  The best I've come up with so far looks
something like:

template <bool>
class CTAssert
    {
    private:

        CTAssert() { }
    };

template <>
class CTAssert<true>
    {
    };

int main()
    {
    CTAssert<true>();           // Compiles without error
    CTAssert<1 == 0>();       // Compiles with error
    return 0;
    }

I have tried it under Microsoft Visual C++ 6, Borland C++ 5.5, and
a couple of other compilers without any problems.  I believe this is
legal according to the standard, but I'm not positive.  Does anyone
see any problems with this code which might cause problems
when ported to other compilers?  I suppose not all compilers
support template specialization yet, so that might be a problem,
but I couldn't come up with a solution which didn't use
specialization...

Thanks...

Dave Asebrook


---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: comeau@panix.com (Greg Comeau)
Date: 2000/04/18
Raw View
In article <38FB3536.26970.108252F7@localhost> "Dave Asebrook" <news@davea.org> writes:
>..assertions at compile time...:
>template <bool>
>class CTAssert {
>    private:
>        CTAssert() { }
>    };
>
>template <>
>class CTAssert<true> { };
>...
>    CTAssert<true>();           // Compiles without error
>    CTAssert<1 == 0>();       // Compiles with error
>
>I have tried it under Microsoft Visual C++ 6, Borland C++ 5.5, and
>a couple of other compilers without any problems.  I believe this is
>legal according to the standard, but I'm not positive.  Does anyone
>see any problems with this code which might cause problems
>when ported to other compilers?  I suppose not all compilers
>support template specialization yet, so that might be a problem,
>but I couldn't come up with a solution which didn't use
>specialization...

It's unclear what you mean when you say that "this is legal"...
What is the "this" that is legal?

IOWs, your program does have an error: CTAssert<tempT>::CTAssert()
is private, and so CTAssert<false>() should produce a diagnostic.
If this is what you want, then ok.  Of course, the above will only
work at compile-time, but you seem to want that...

- Greg
--
Comeau Computing, Producers of Comeau C/C++ 4.2.42 (4.2.43 BETA starting)
Try Comeau C++ online at http://www.comeaucomputing.com/tryitout
Email: comeau@comeaucomputing.com / WEB: http://www.comeaucomputing.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]