static_assert vs assert

Mar 3, 2017 at 7:18pm
I have searched this on google and found some help on stack_overflow

http://stackoverflow.com/questions/18210270/what-is-the-difference-between-assert-and-static-assert

, but when I tried using

 
static_assert(test::size > test::capacity, "Failed!");

The cpp shell program gave me this error: "non-constant condition for static assertion".


Also I tried using
 
assert("failed", size > capacity)
, but it says that assert can only have one argument, not two.


What should I do guys?
Last edited on Mar 3, 2017 at 7:19pm
Mar 3, 2017 at 7:50pm
Not clear what test::size and test::capacity are. Are they member variables?

In any case, static_assert applies only at compile time, therefore, the first argument must be a constant known at compile time. If size and capacity are member variables, then the compiler does not know their values are at compile time.

Yes, assert takes only one argument (an int). It does not accept a message argument. The message output when the assertion is raised is usually a token paste of the argument.

Mar 3, 2017 at 7:58pm
@AbstractionAnon,

test is my class name, and size and capacity are my variables inside private, which we call ember variables.

I want to write an assert inside my public class.

So you mean I should write it like this ? I tried, but it didn't work. Could you please show me what you mean by constant.

static_assert const (test::size > test::capacity, "Failed!");
Last edited on Mar 3, 2017 at 7:59pm
Mar 3, 2017 at 8:04pm
No, as I said before, you can't use member variables. The value of a member variable is unknown at compile time.

Try this:
 
  assert (size <= capacity); 


Note that the assert must be inside a member function of your class. i.e. It must have access to an instance's member variables.






Mar 3, 2017 at 8:16pm
Ok, yes I am using assert (size < capacity) in my public part of class. It has access to the values of the member variables since public methods and member functions access member variables inside private.

I want to know how can I print a "Failed!" message if assert condition does not work ?
Mar 3, 2017 at 8:52pm
I want to know how can I print a "Failed!" message if assert condition does not work ?

You can't directly.

You could do something like this:
1
2
3
4
5
6
#define myassert(cond,msg)                  \
               {  if (! (cond))             \
                   {  cerr << msg << endl;  \
                     assert (false);        \
                   }                        \
               } 

Mar 3, 2017 at 10:18pm
Haha, programming is really funny. Just when you think you reached the top peak of the mountain, you'll then see another mountain behind it.


Awsome ,@AbstractionAnon, it worked! Thanks! My teacher never taught me this, just the syntax for assert, but I like learning new things on my own.
Mar 3, 2017 at 10:33pm
Honestly, assert is mostly a debugging tool. Better to try/throw/catch etc and unwind gracefully than to just suicide with a cryptic warning.

I haven't used an assert since college.
Mar 3, 2017 at 11:08pm
The diagnostic information generated by the macro assert includes the text of the expression (in addition to __func__, __FILE__ and __LINE__); ideally do not supress it.

To print out a custom message if the assertion fails, this would suffice:
assert( condition && "my cutom message" ) ;

If we want to write a replacement macro my_assert:

<cassert> is a header where including it multiple times is not idempotent; the lexically current definition of NDEBUG is relevant each time it is #included.

So place the definition of the macro in a header file, outside the include guard.
(We want to redefine it each time it is #included.)

Something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <cassert>

#ifdef my_assert
    #undef my_assert
#endif // my_assert

#ifdef NDEBUG
   #define my_assert( cond, msg ) ( void(0) )
#else
   #define my_assert( cond, msg ) \
      if( !(cond) ) std::cerr << "invariant (" << #cond << ") does not hold : " << (msg) << '\n' ; \
      assert(cond)
#endif // NDEBUG 

http://coliru.stacked-crooked.com/a/4b2b039691ee3d24
Mar 4, 2017 at 12:36am
> Honestly, assert is mostly a debugging tool. Better to try/throw/catch etc and unwind gracefully
> than to just suicide with a cryptic warning. I haven't used an assert since college.

Assert liberally to document internal assumptions and invariants

Summary

Be assertive! Use assert or an equivalent liberally to document assumptions internal to a module (i.e., where the caller and callee are maintained by the same person or team) that must always be true and otherwise represent programming errors (e.g.,violations of a function's post-conditions detected by the caller of the function). Ensure that assertions don't perform side effects.


Discussion

...
It is hard to overestimate the power of assertions. The assert macro and alternatives such as compile-time (and, less preferably, run-time) assertion templates are invaluable tools for detecting and debugging programming errors during a project's development. Of all such tools, they arguably have the best complexity/effectiveness ratio. The success of a project can be conditioned at least in part by the effectiveness with which developers use assertions in their code.
...
It is not recommended to throw an exception instead of asserting, even though the standard std::logic_error exception class was originally designed for this purpose. The primary disadvantage of using an exception to report a programming error is that you don't really want stack unwinding to occur — you want the debugger to launch on the exact line where the violation was detected, with the line's state intact.

In sum: There are errors that you know might happen.
For everything else that shouldn't, and it's the programmer's fault if it does, there is assert.

Alexandresu and Sutter in 'C++ Coding Standards - 101 Rules, Guidelines, and Best Practices'
Topic archived. No new replies allowed.