Code littered with asserts - c++

Hi I am programming on some device.
There is some sample with such code:
Verify(SomeFunc(argc, argv) == SDK_OK);
Verify(SomeOtherFunction(&st_initialData) == SDK_OK);
Verify(SomeOtherFunction2(x,y) == SDK_OK);
In doc, Verify is defined as 'similar' to assert.
My question is: if I build my project in Release mode, what will happen with above statements? Will they lose their power? Will the Verify have any effect still?
To avoid possible problem with above, will I have to replace above codes with checking return values like this?:
if(SomeFunc(argc, argv) == SDK_OK)
{
// we are fine
}
else
{
// handle error somehow, such that it is also available in Release mode
}

It is impossible to say, as it seems that it is your project which implements Verify, as a macro or as a function. Why don't you take a look at the implementation?
That being said, MFC framework has VERIFY macro which is similar to ASSERT, with the distinction that the expression is always evaluated, even in release build, but doesn't do anything if result of the expression is false. This might be the similar approach, as your examples seem to call some functions which can affect the system state.

I assume you mean the MFC VERIFY macro or something very similar.
Using this macro is safe for release builds. The argument is executed in any case, just the macro itself does nothing in release.
In contrast to this, the ASSERT macro is completely skipped in release builds, so the "side effects" of the argument do not happen. Therefore, VERIFY is used if the argument is required for the actual program flow, and ASSERT is used when the argument is for asserting only.

Almost certainly you will not have to replace them. If your project wanted just to remove the calls in production compilation, it would probably have just plain assert directly. Try to read the source of the project (always a good idea) and understand what he macro does.

Related

Insert text into C++ code between functions

I have following requirement:
Adding text at the entry and exit point of any function.
Not altering the source code, beside inserting from above (so no pre-processor or anything)
For example:
void fn(param-list)
{
ENTRY_TEXT (param-list)
//some code
EXIT_TEXT
}
But not only in such a simple case, it'd also run with pre-processor directives!
Example:
void fn(param-list)
#ifdef __WIN__
{
ENTRY_TEXT (param-list)
//some windows code
EXIT_TEXT
}
#else
{
ENTRY_TEXT (param-list)
//some any-os code
if (condition)
{
return; //should become EXIT_TEXT
}
EXIT_TEXT
}
So my question is: Is there a proper way doing this?
I already tried some work with parsers used by compilers but since they all rely on running a pre-processor before parsing, they are useless to me.
Also some of the token generating parser, which do not need a pre-processor are somewhat useless because they generate a memory-mapping of tokens, which then leads to a complete new source code, instead of just inserting the text.
One thing I am working on is to try it with FLEX (or JFlex), if this is a valid option, I would appreciate some input on it. ;-)
EDIT:
To clarify a little bit: The purpose is to allow something like a stack trace.
I want to trace every function call, and in order to follow the call-hierachy, I need to place a macro at the entry-point of a function and at the exit point of a function.
This builds a function-call trace. :-)
EDIT2: Compiler-specific options are not quite suitable since we have many different compilers to use, and many that are propably not well supported by any tools out there.
Unfortunately, your idea is not only impractical (C++ is complex to parse), it's also doomed to fail.
The main issue you have is that exceptions will bypass your EXIT_TEXT macro entirely.
You have several solutions.
As has been noted, the first solution would be to use a platform dependent way of computing the stack trace. It can be somewhat imprecise, especially because of inlining: ie, small functions being inlined in their callers, they do not appear in the stack trace as no function call was generated at assembly level. On the other hand, it's widely available, does not require any surgery of the code and does not affect performance.
A second solution would be to only introduce something on entry and use RAII to do the exit work. Much better than your scheme as it automatically deals with multiple returns and exceptions, it suffers from the same issue: how to perform the insertion automatically. For this you will probably want to operate at the AST level, and modify the AST to introduce your little gem. You could do it with Clang (look up the c++11 migration tool for examples of rewrites at large) or with gcc (using plugins).
Finally, you also have manual annotations. While it may seem underpowered (and a lot of work), I would highlight that you do not leave logging to a tool... I see 3 advantages to doing it manually: you can avoid introducing this overhead in performance sensitive parts, you can retain only a "summary" of big arguments and you can customize the summary based on what's interesting for the current function.
I would suggest using LLVM libraries & Clang to get started.
You could also leverage the C++ language to simplify your process. If you just insert a small object into the code that is constructed on function scope entrance & rely on the fact that it will be destroyed on exit. That should massively simplify recording the 'exit' of the function.
This does not really answer you question, however, for your initial need, you may use the backtrace() function from execinfo.h (if you are using GCC).
How to generate a stacktrace when my gcc C++ app crashes

Assert() - what is it good for ?

I don't understand the purpose of assert() .
My lecturer says that the purpose of assert is to find bugs .
For example :
double divide(int a , int b )
{
assert (0 != b);
return a/b;
}
Does the above assert justified ? I think that the answer is yes , because if my program
doesn't supposed to work with 0 (the number zero) , but somehow a zero does find its way into the b variable , then something is wrong with the code .
Am I correct ?
Can you show me some examples for a justified assert() ?
Regards
assert is used to validate things that should always be true if the
program is correct. Whether assert is justified in your example
depends on the specification of divide: if b != 0 is a precondition,
then the assert is usually the preferred way of verifying it: if
someone calls the function without fulfilling the preconditions, it is a
programming error, and you should terminate the program with extreme
prejudice, doing as little additional work as possible. (Usually.
There are applications where this is not the case, and where it is
better to throw an exception, and stumble along, hoping for the best.)
If, however, the specification of divide defines somw behavior when b
== 0 (e.g. return +/-Inf), then you should implement this instead of
using assert.
Also, it's possible to turn the assert off, if it turns out that it
takes too much runtime. Generally, however, this should only be done in
critical sections of code, and only if the profiler shows that you
really need it.
FWIW: not related to your question, but the code you've posted will
return 0.0 for divide( 1, 3 ). Somehow, I don't think that this is
what you wanted.
Another aspect of assertions:
They are also a kind of documentation.
Instead of comments like
// ptr is never NULL
// vec has now n elements
better write
assert(ptr!=0);
assert(vec.size()==n);
Comments may become outdated over time and will cause confusion.
But assertions are verified all the time.
Comments can be ignored. Assertions cannot.
You're pretty much spot-on in your assesment of assert, except for the fact you typically use assert during a debug-phase ... This is because you don't want an assert to trigger during production code ... throwing exceptions (and properly handling them) is the proper method for run-time error-management in production level code.
In general though, assert is used for testing an assumption. If an assumed condition is not met in the code during the debugging phase, especially when you are getting values that are out-of-bound for the desired input, you want your program to bail out at the point that the error is encountered so you can fix it. For instance, suppose you were calling a function that returned a pointer, and that function should never return a NULL pointer value. In other words returning a NULL value is not just some indicator of an error-condition, but it means that the assumption of how you imagine your code works is wrong. That is a good place to use assert ... you assume your program will work one way, and if it doesn't then you don't want that error propagating to cause some crazy hard-to-find bug somewhere else ... you want to nix it right when it occurs.
Finally, you can combine built in macros with assert such as __LINE__ and __FILE__ that will give you the file and line number in the code where the assert took place to help you quickly identify the problem area.
The purpose of an assert is to signal out unexpected behavior during debugging (as it's only available in a debug build). Your example is a justified case of assert. The next line would probably crash, but with the assert there you have the option to break execution right before the line is hit, and do some debugging.
This is usually done in parallel with exceptions - you assert to signal that something is wrong, and throw an exception to treat the case gracefully (even exiting the program):
double divide(int a , int b )
{
assert (0 != b);
if ( b )
return a/b;
throw division_by_0_exception();
}
There are cases where you want to continue execution, but still want to signal that something went wrong.
Assert is used to test assumptions about your code in a debug environment. Asserts generally have no effect on your final build.
Whether or not it is a valid test is another matter entirely. We can't answer that without intimate knowledge of your application.
Asserts should never fail. If you see any possibility that the assertion could fail, then you need an if statement instead to handle those cases where the condition is not true. Assertions are only for conditions that you believe will never fail.
Asserts are used to check invariants during code execution, those are the conditions that are assumed by programmer to always stay the same, if they differ from assumptions then there is a bug in the code.
Asserts can be also used for checking preconditions and postconditions, the first is checked before some code block and verifies if provided data/state is correct, the second one checks whether the outcome of some calculations are correct. This helps to narrow where problems/bugs might be located:
assert( /*preconditions*/ );
/*here some algorithm - and maybe more asserts checking invariants*/
assert( /*postconditions*/ );
Some examples of justified asserts:
Checking function return value, for example if you call some external API function and you know that it returns some error value only in case of programming error:
WinAPI Thread32First function requires that provided LPTHREADENTRY32 structure has properly assigned dwSize field, in case of error it fails. This failure should be catched by assert.
If function accepts pointer to some data, then add assert at the start of function to verify that it is non-null. This makes sense if this function cannot work on null pointer.
If you have a lock on mutex with set timeout then if this timeout ends then you can use assert to indicate possible race condition / deadlock
... and many many more
Nice trick with asserts is to add some info inside, ex.:
assert(false && "Reason for this assert");
"Reason for this assert" will show up to you in a message box
You might also want to know that we also have static asserts that indicate errors during compilation.

Assertion Failed in C++ questions

Running into an issue with some code I'm working on. This code is being run on a linux-based system and the error I receive is the following:
/root/cvswork/pci_sync_card/Code/SSBSupport/src/CRCWbHfChannel/CRCWbHfMSBSimulator.cpp:447:
virtual void CCRCWbHfMSBSimulator::Process(): Assertion 'pcBasebandOutput' failed.
I've tried stepping through this code to figure out why this is failing and I can't seem to figure it out. Unfortunately I have too many files to really share the code on here (stepping through the pcBasebandOutput assignment takes quite some time). I understand this is a more complex issue than can really be asked about. My primary questions are these:
Is my assert(pcBasebandOutput); line of code necessary? I only ask because when running this code on Visual Studio, the results from my program were desirable.
When it is evaluating my pcBasebandOutput variable, why would it evaluate it as false? Is this saying that no value is actually assigned to pcBasebandOutput? Or that a value may be assigned to it, but it is not of the right type (pointer to a struct of two variables, both of which are doubles)?
Thanks!
assert checks a logical condition. Assertation fails if the condition is false. So writing assert(cond) is logically the same as writing:
if (!cond)
{
assert(false);
}
I don't suggest you to remove assert from the code, because it is a guard telling you that something went not the way it's intended to go. And it's not a god idea just to ignore that, because it may shoot you in a leg later
Only you can know that
What is the type of pcBasebandOutput ? Maybe it is not properly initialized?
assert primary purpose is to allow your IDE to enter debuging session in the place where assert has hit. From there you can read all variables and see callstack/threads. Other solution (than using debugger) is to add lots of logging, which in threaded environments can cause problems on its own (logging is quite slow).

assertions in native c++ / debugging

example of using assertions during debugging:
char* append(char* pStr, const char* pAddStr)
{
// Verify non-null pointers
assert(pStr != nullptr);
assert(pAddStr != nullptr);
// Code to append pAddStr to pStr...
}
Calling the append() function with a null pointer argument in a simple program produced the following diagnostic message on my machine:
Assertion failed: pStr != nullptr, file c:\beginning visual c++ 2010\examples visual studio project files\tryassertion\tryassertion\tryassertion.cpp, line 10
I would like to know if assertions are neccesary. What is the point of using them if i can use if-else expressions to output my own error messages?
An assertion is a conditional check; it's just a macro that's something like this (simplified):
#define assert(b) if (!(b)) { std::cerr << ...; exit(1); }
I can think of two advantages:
When you compile in release mode (i.e. not in debug mode), then all the asserts will compile away to nothing, so you will incur no runtime overhead.
assert is an idiom; other programmers know to look for them, and they're also distinct from "normal" control flow.
assertions are used to ensure that certain basic assumptions are met. Basically you put in an assertation in every case which "couldnt possibly happen", most commonly assertions how the API has to be used e.g. preconditions and postconditions (like your example, which contains asserts which check the correct usage of your append function). For other errors, which are known to occur during runtime and which cannot be prevented beforehand (e.g. file-not-found or insufficient-permissions kind of errors), you will have to write error handling code.
Assertions are not included in release compilations, so they can only be used to catch critical programming errors, which will already occur in debug-mode test runs.
You should use assertions when the only case in which they are violated is an error in the program logic. You use normal if-then-else conditionals for things that may indeed happen because of input or external possible conditions (i.e. a file is missing).
When you know for sure that the program logic is faulty there is not really much sense in trying to continue execution... your program is working differently from what you think (because otherwise the assertion wouldn't have been triggered) and therefore the best option is just to yell what the problem is and die immediately.
Often assertion are removed when the code is compiled in "release" mode even if however it may make sense to keep them in place if the program logic is very complex and if continuing execution generating bad output is going to create bigger problems than stopping execution.
Note that a "trap" that sometimes novice programmers fall into with assertion is that when the assertion code is removed for release mode the expression inside the assert is not evaluated any more, and therefore if you program depends on side effects of that expression then you're going to be in trouble... for example:
...
assert(insert_record(db, data) == DB_OK); // <== this is bad
...
when assertion are defined away the insertion will not happen at all, leaving you with a program that doesn't work in release mode and that works instead when you try to debug the problem.

What are assertions? and why would you use them?

How are assertions done in c++? Example code is appreciated.
Asserts are a way of explicitly checking the assumptions that your code makes, which helps you track down lots of bugs by narrowing down what the possible problems could be. They are typically only evaluated in a special "debug" build of your application, so they won't slow down the final release version.
Let's say you wrote a function that took a pointer as an argument. There's a good chance that your code will assume that the pointer is non-NULL, so why not explicitly check that with an assertion? Here's how:
#include <assert.h>
void function(int* pointer_arg)
{
assert(pointer_arg != NULL);
...
}
An important thing to note is that the expressions you assert must never have side effects, since they won't be present in the release build. So never do something like this:
assert(a++ == 5);
Some people also like to add little messages into their assertions to help give them meaning. Since a string always evaulates to true, you could write this:
assert((a == 5) && "a has the wrong value!!");
Assertion are boolean expressions which should typically always be true.
They are used to ensure what you expected is also what happens.
void some_function(int age)
{
assert(age > 0);
}
You wrote the function to deal with ages, you also 'know' for sure you're always passing sensible arguments, then you use an assert. It's like saying "I know this can never go wrong, but if it does, I want to know", because, well, everyone makes mistakes.
So it's not to check for sensible user input, if there are scenario's where something can go wrong, don't use an assert. Do real checks and deal with the errors.
Asserts are typically only for debug builds, so don't put code with side effects in asserts.
Assertions are used to verify design assumptions, usually in terms of input parameters and return results. For example
// Given customer and product details for a sale, generate an invoice
Invoice ProcessOrder(Customer Cust,Product Prod)
{
assert(IsValid(Cust));
assert(IsValid(Prod);
'
'
'
assert(IsValid(RetInvoice))
return(RetInvoice);
}
The assert statements aren't required for the code to run, but they check the validity of the input and output. If the input is invalid, there is a bug in the calling function. If the input is valid and output is invalid, there is a bug in this code. See design by contract for more details of this use of asserts.
Edit: As pointed out in other posts, the default implementation of assert is not included in the release run-time. A common practice that many would use, including myself, is to replace it with a version that is included in the release build, but is only called in a diagnostics mode. This enables proper regression testing on release builds with full assertion checking. My version is as follows;
extern void _my_assert(void *, void *, unsigned);
#define myassert(exp) \
{ \
if (InDiagnostics) \
if ( !(exp) ) \
_my_assert(#exp, __FILE__, __LINE__); \
} \
There is a small runtime overhead in this technique, but it makes tracking any bugs that have made it into the field much easier.
Use assertions to check for "can't happen" situations.
Typical usage: check against invalid/impossible arguments at the top of a function.
Seldom seen, but still useful: loop invariants and postconditions.
Assertions are statements allowing you to test any assumptions you might have in your program. This is especially useful to document your program logic (preconditions and postconditions). Assertions that fail usually throw runtime errors, and are signs that something is VERY wrong with your program - your assertion failed because something you assumed to be true was not. The usual reasons are: there is a flaw in your function's logic, or the caller of your function passed you bad data.
An assertion is something you add to your program that causes the program to stop immediately if a condition is met, and display an error message. You generally use them for things which you believe can never happen in your code.
This doesn't address the assert facility which has come down to us from early C days, but you should also be aware of Boost StaticAssert functionality, in the event that your projects can use Boost.
The standard C/C++ assert works during runtime. The Boost StaticAssert facility enables you to make some classes of assertions at compile time, catching logic errors and the like even earlier.
Here is a definition of what an assertion is and here is some sample code. In a nutshell an assertion is a way for a developer to test his (or her) assumptions about the state of the code at any given point. For example, if you were doing the following code:
mypointer->myfunct();
You probably want to assert that mypointer is not NULL because that's your assumption--that mypointer will never be NULL before the call.