Expressive assertion failure messages in C++ - c++

Unit test frameworks generally provide very nice assertion failure messages (I'm using gtest) describing expected and actual values to a particular test. Furthermore, you know the origin of the function call because you're testing the interface of the class.
In contrast, assert, when used as a sanity check in the implementation provides some, but more cryptic information. For example, the one I'm working on now . .
Assertion failed: (latency > std::chrono::milliseconds(0)), function setLatency, file /path/to/my.cpp line 71
So I know which assertion failed, but I have no idea what the values were that caused it to fail, and more importantly, I don't know the problematic function from which setLatency was called.
A simple solution normally would be drop to the debugger, but I cannot do this in this instance. Is it possible to get a more descriptive assertion message from within the implementation of a class? How can I do this? I don't mind using a 3rd party lib if necessary.

A common solution for this problem is to create an assert macro. For an example see this question. The final form of their macro in that answer was the following:
#define dbgassert(EX,...) \
(void)((EX) || (realdbgassert (#EX, __FILE__, __LINE__, ## __VA_ARGS__),0))
In your case, the realdbgassert would be a function that prints any relevant information to stderr or other output console, and then calls the assert function itself. Depending on how much information you want, you could also do a stack dump, or log any other relevant information that will help you identify the issue. However, it can be as simple as passing a printf-esque format string, and relevant parameter value(s).
Note that if you compiler doesn't support variadic macros, you can create macros that take a specific number of parameters instead. This is slightly more cumbersome, but an option if your compiler lacks the support, eg:
#define dbgassert0(EX) \ ...
#define dbgassert1(EX,p0) \ ...
#define dbgassert2(EX,p0,p1) \ ...

I am not sure if this is what you are looking for, but you can append any message you like to the "Assertion failed:.." message by doing something like this:
assert(1==1 && "This is always true");
assert(1==0 && "This always fails");
Of course you can modify the string to contain values or more information.

Related

How to catch up specific method calls in a kind of logging mechanism

I'm implementing a logger for an OpenGL application ( the only reason I'm mentioning it is that it runs in a loop ). I'd like to somehow log every method call or some group of method calls of some classes, every time they are called.
My initial approach was to place the required logger function call in all the methods ( which actually kind of works like comments :) ) but I got really tired of it really fast, so I started looking for a more effective way. I searched google for some time, but since I don't really know what I'm looking for, I ran out of ideas.
The best thing for my case would be some kind of magical method, that would be called every time I invoked any other class method, idealy with name and params string as a parameter for this method. ( kind of PHP - like magic method __call() - but that one works only if method is not defined ). I don't know what I am looking for, if something like that even exists, and if it does, what do we call it?
P.S.:
my logging works on macros, so no worries for performance there :)
#if DEV_LOG
#define log_init() logInit()
#define log_write(a,b) writeToLog(to_str(a), to_str(b))
#else
#define log_init()
#define log_write(a,b)
#endif
( And if there's a nicer way to do this, let me know, please :) )
Thank you!
1st I have to re-cite my co-answerer Filip here
C++ doesn't have this kind of "magical method", so you are stuck with explicitly stating a function call inside every member-function, if you'd like one to be made.
Such stuff is implemented as compiler specific features like the GCC profiling. There will be code generated to track for function calls, their parameters, and where these actually were called from and how often.
The general usage is to compile and link your code with special compiler flags that will generate this code. When your code is run, this information will be stored along specific kind of databases, that can be analyzed with a separate tool after running (as e.g. gprof for the GCC toolchain).
A similar tooling suite is used for retrieving code coverage of certain program runs (e.g. testsuites for your code): gcov A Test Coverage Program
C++ doesn't have this kind of "magical method", so you are stuck with explicitly stating a function call inside every member-function, if you'd like one to be made.
You could instead use a debugger to track the calls made, the program you've written shouldn't have to be responsible for questions such as "what code is called, when and with what?"; that's the exact question a profiler, or a debugger, was made to answer.

Get return type of function in macro (C++)

I have ASSERT(x) macro and I want to call return if it asserts (in release configuration).
To do this I need to know return type of function where I use this ASSERT. How to get it (I deal with C++03, LLVM GCC 4.2 compiler)?
My ASSERT macro:
#define ASSERT(x) \
if(!(x)) {
LOG ("ASSERT in %s: %d", __FILE__, __LINE__); \
return /*return_type()*/; \
}
PS: I tried return 0; - compiler shows error for void functions (and I didn't try it for complex returning types), if return; - error for non-void functions.
(Updated...)
I'll answer to werewindle, nyarlathotep and jdv-Jan de Vaan here. I use standard assert for debug configuration. But after beta-testing I still get crash reports from final customers, and in most cases I need to change my crashing functions:
ASSERT (_some_condition_);
if (!_some_condition_) // add this return
return _default_value_;
I understand, that my program may crash probably later (otherwise it will definitely crash in current function). Also I can't quit application because developing is for iPhone (apps may not quit programmatically there). So the easiest way would be to "auto return" when assertion failed.
You can't determine the return type of the surrounding function in a Macro; macros are expanded by the preprocessor, which doesn't have this kind of information about the surroundings where these macros occur; it is basically just "searching and replacing" the macros. You would have to write separate macros for each return type.
But why not exit the program (i.e. calling the exit function)? Just returning from a function doesn't seem like a very robust error handling. Failed assertions should after all only occur when something is terribly wrong (meaning the program is in a state it was not designed to handle), so it is best to quit the program as soon as possible.
There are no proper way to determine return type inside a function in C.
Also, if you somehow implement your variant of ASSERT it will lead to erroneous program behavior. Main idea of ASSERT: if it fails, then program is in undefined state and only proper way is to stop it now. I.e. by calling exit().
i think you can do this with a template function, that you call default(x) from within the macro.
template<class T> default<T>(T x) { return T(); }
that will work for everyting with a default constructor. I think you need to write a special macro for void.
I hope i got the template syntax right, my c++ is getting rusty.
You can't do that, the C/C++ preprocessor is pretty basic and it can't do any code analysis. At most what you can do is pass the return type to the macro.
But here's my opinion: you're using assertions the wrong way. They should only be used for sanity checks of the code (for errors than can only happen because of the programmer); if all assertions pass, you don't need to care about them, you don't need to log them.
And not only that, but (in general) you should employ the element of least surprise. Do you expect ASSERT to log something and then forcefully make the function return? I know I wouldn't. I either expect it to close the application completely (what the standard assert does) or let me decide what happens next (maybe I have some pointers to free).
Macros do not return values, as they are no functions per se. They substitute the source code where they are used, so you'd return in the function where the macro is used.
There is no way to get the return value from a macro.
You could just define another macro for your needs.
#define ASSERT(x) \
if(!(x)) { \
LOG ("ASSERT in %s: %d", __FILE__, __LINE__); \
ASSERT_DEFAULT_RETURN(); \
}
And then inside a function:
int foo(){
#ifdef ASSERT_DEFAULT_RETURN
#undef ASSERT_DEFAULT_RETURN
#endif
#define ASSERT_DEFAULT_RETURN() return 0
// ...
ASSERT(some_expression);
// ...
// cleanup
#undef ASSERT_DEFAULT_RETURN
}
Just do this
#define ASSERT(x, ret, type) \
if(!(x)){
LOG ("ASSERT in %s: %d", __FILE__, __LINE__); \
return (type) ret;
}
I believe you are trying to solve the wrong problem. You don't want your program to crash in case of assertions, you best improve your testing.
Having a 'return' in these assertions give you a false sense of security. Instead it hides your problems and causes unexpected behavior in your program so the bugs you do get are much more complex. A colleague of mine actually wrote a good blog post about it.
If you really would want it, you could try writing return {}; so it default constructs the value, or have an assert macro where you also provide the failure case. However I really don't recommend it!

How to separate logging logic from business logic in a C program? And in a C++ one?

I am currently coding in C and I have lots of printfs so that I can track, at some times, the flow of my application. The problem is that some times I want more detail than others, so I usually spend my time commenting/uncommenting my C code, so I can get the appropriate output.
When using Java or C#, I can generally separate both my implementation code from the logging logic by using Aspects.
Is there any similar technique you use in C to get around this problem?
I know I could put a flag called DEBUG that could be either on or off, so I wouldn't have to go all around and comment/uncomment my whole code every time I want to either show or hide the printfs. The question is I'd like to also get rid of the logging logic in my code.
If instead of C I was coding in C++, would it be any better?
Edit
It seems there is an AspectC++, so for C++ there seems to be a solution. What about C?
Thanks
IME you cannot really separate logging from the algorithms that you want to log about. Placing logging statements strategically takes time and experience. Usually, the code keeps assembling logging statements over its entire lifetime (though it's asymptotic). Usually, the logging evolves with the code. If the algorithm changes often, so will usually the logging code.
What you can do is make logging as unobtrusive as possible. That is, make sure logging statements always are one-liners that do not disrupt reading the algorithm, make it so others can insert additional logging statements into an existing algorithm without having to fully understand your logging lib, etc.
In short, treat logging like you treat string handling: Wrap it in a nice little lib that will be included and used just about everywhere, make that lib fast, and make it easy to use.
Not really.
If you have variadic macros available, you can easily play games like this:
#ifdef NDEBUG
#define log(...) (void)0
#else
#define log(...) do {printf("%s:%d: ", __FILE__, __LINE__); printf(__VA_ARGS__);} while(0)
#endif
You can also have logging that's turn-off-and-onable at a finer granularity:
#define LOG_FLAGS <something>;
#define maybe_log(FLAG, ...) do { if (FLAG&LOG_FLAGS) printf(__VA_ARGS__);} while(0)
int some_function(int x, int y) {
maybe_log(FUNCTION_ENTRY, "x=%d;y=%d\n", x, y);
... do something ...
maybe_log(FUNCTION_EXIT, "result=%d\n", result);
return result;
}
Obviously this can be a bit tedious with only allowing a single return from each function, since you can't directly get at the function return.
Any of those macros and calls to printf could be replaced with something (other macros, or variadic function calls) that allows the actual logging format and target to be separated from the business logic, but the fact of some kind of logging being done can't be, really.
aspectc.org does claim to offer a C and C++ compiler with language extensions supporting AOP. I have no idea what state it's in, and if you use it then of course you're not really writing C (or C++) any more.
Remember that C++ has multiple inheritance, which is sometimes helpful with cross-cutting concerns. With enough templates you can do remarkable things, perhaps even implementing your own method dispatch system that allows some sort of join points, but it's a big thing to take on.
On GCC you could use variadic macros: http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html . It makes possible to define dprintf() with any number of parameters.
Using additional hidden verbose_level parameter you can filter the messages.
In this case the logging loggic will only contain
dprintf_cond(flags_or_verbose_level, msg, param1, param2);
and there will be no need in separating it from the rest of code.
A flag and proper logic is probably the safer way to do it, but you could do the same at compile type. Ie. Use #define and #ifdef to include/exclude the printfs.
Hmm, this sounds similar to a problem I encountered when working on a C++ project last summer. It was a distributed app which had to be absolutely bulletproof and this resulted in a load of annoying exception handling bloat. A 10 line function would double in size by the time you added an exception or two, because each one involved building a stringstream from a looong exception string plus any relevant parameters, and then actually throwing the exception maybe five lines later.
So I ended up building a mini exception handling framework which meant I could centralise all my exception messages inside one class. I would initialise that class with my (possibly parameterised) messages on startup, and this allowed me to write things like throw CommunicationException(28, param1, param2) (variadic arguments). I think I'll catch a bit of flak for that, but it made the code infinitely more readable. The only danger, for example, was that you could inadvertently throw that exception with message #27 rather than #28.
#ifndef DEBUG_OUT
# define DBG_MGS(level, format, ...)
# define DBG_SET_LEVEL(x) do{}while(0)
#else
extern int dbg_level;
# define DBG_MSG(level, format, ...) \
do { \
if ((level) >= dbg_level) { \
fprintf(stderr, (format), ## __VA_ARGS__); \
} \
} while (0)
# define DBG_SET_LEVEL(X) do { dbg_level = (X); } while (0)
#endif
The ## before __VA_ARGS__ is a GCC specific thing that makes , __VA_ARGS__ actually turn into the right code when there are no actual extra arguments.
The do { ... } while (0) stuff is just to make you put ; after the statements when you use them, like you do when you call regular functions.
If you don't want to get as fancy you can do away with the debug level part. That just makes it so that if you want you can alter the level of debugging/tracing date you want.
You could turn the entire print statement into a separate function (either inline or a regular one) that would be called regardless of the debug level, and would make the decision as to printing or not internally.
#include <stdarg.h>
#include <stdio.h>
int dbg_level = 0;
void DBG_MGS(int level, const char *format, ...) {
va_list ap;
va_start(ap, format);
if (level >= dbg_level) {
vfprintf(stderr, format, ap);
}
va_end(ap);
}
If you are using a *nix system then you should have a look at syslog.
You might also want to search for some tracing libraries. There are a few that do similar things to what I have outlined.

compile time assertions *across modules* / c,c++

recently i discovered in a relatively large project, that ugly runtime crashes occurred because various headers were included in different order in different cpp files.
These headers included #pragma pack - and these pragmas were sometimes not 'closed' ( i mean, set back to the compiler default #pragma pack() ) - resulting in different object layouts in different object files. No wonder the application crashed when it accessed struct members being created in one module and passed to another module. Or derived classes accessing members from base classes.
Since i like the idea to create a more general debugging and assertion strategy from every bug i find, i would really like to assert that object layouts are always and everywhere the same.
So it would be easy to assert
ASSERT( offsetof(membervar) == 4 )
But this would not catch a different layout in another module - or require manual updates whenever the struct layout changes .. so my favourite idea would be something like
ASSERT( offsetof(membervar) == offsetof(othermodule_membervar) )
Would this be possible with an assertion? Or is this a case for a unit test?
Thanks,
H
ASSERT( offsetof(membervar) == offsetof(othermodule_membervar) )
I can't see way to make this technically possible. Further, even if it was phyiscally possible, it isn't practical. You'd need an assert for every pair of source files:
ASSERT( offsetof(A.c::MyClass.membervar) == offsetof(B.c::MyClass.membervar) )
ASSERT( offsetof(A.c::MyClass.membervar) == offsetof(C.c::MyClass.membervar) )
ASSERT( offsetof(A.c::MyClass.membervar) == offsetof(D.c::MyClass.membervar) )
ASSERT( offsetof(B.c::MyClass.membervar) == offsetof(C.c::MyClass.membervar) )
ASSERT( offsetof(B.c::MyClass.membervar) == offsetof(D.c::MyClass.membervar) )
etc
You might be able to get away with this by asserting the sizeof(class) in different files. If the packing is causing the size of the object to be smaller, than I would expect that sizeof() would show that up.
You could also do this as a static assert using C++0x's static assert, or Boost's (or a handrolled one of course)
On the part of not wanting to do this in every file, I would recommend putting together a header file that includes all the headers you're worried about, and the static_asserts.
Personally though, I'd just recommend searching through the code base over the list of pragmas and fix them.
Wendy,
In Win32, there are single functions that can populate different versions of a given struct. Over the years, the FOOBAR struct might have new features added to it, so they create a FOOBAR2 or FOOBAREX. In some cases there are more than two versions.
Anyway, the way they handle this is to have the caller pass in sizeof(theStruct) in addition to the pointer to the struct:
FOOBAREX foobarex = {0};
long lResult = SomeWin32Api(sizeof(foobarex), &foobarex);
Within the implementation of SomWin32Api(), they check the first parameter and determine which version of the struct they're dealing with.
You could do something similar in a debug build to assure that the caller and callee agree on the size of the struct being referred to, and assert if the value doesn't match the expected size. With macros, you might even be able to automate/hide this so that it only happens in a debug build.
Unfortunately, this is a run-time check and not a compile-time check...
What you want isn't directly possible as such. If you're using VC++, the following may be of interest:
http://blogs.msdn.com/vcblog/archive/2007/05/17/diagnosing-hidden-odr-violations-in-visual-c-and-fixing-lnk2022.aspx
There's probably scope to create some way of semi-automating the process it describes, collating the output and cross-referencing.
To detect this sort of problem somewhat more automatically, the following occurs to me. Create a file that defines a struct that will have a particular size with the designated default packing amount, but a different size with different pack values. Also include some kind of static assert that its size is correct. For example, if the default is 4-byte packing:
struct X {
char c;
int i;
double d;
};
extern const char g_check[sizeof(X)==16?1:-1];
Then #include this file at the start of every header (just write a program to put the extra includes in if there's too many to do by hand), and compile and see what happens. This won't directly detect changes in struct layout, just non-standard packing settings, which is what you're interested in anyway.
(When adding new headers one would put this #include at the top, along with the usual ifdef boilerplate and so on. This is unfortunate but I'm not sure there's any way around it. The best solution is probably to ask people to do it, but assume they'll forget, and run the extra-include-inserting program every now and again...)
Apologies for posting an answer - which this is not - but I don't know how to post code in comments. Sorry.
To wrap Brone's idea in a macro, here is what free we currently use (feel free to edit it):
/** Our own assert macro, which will trace a FATAL error message if the assert
* fails. A FATAL trace will cause a system restart.
* Note: I would love to use CPPUNIT_ASSERT_MESSAGE here, for a nice clean
* test failure if testing with CppUnit, but since this header file is used
* by C code and the relevant CppUnit include file uses C++ specific
* features, I cannot.
*/
#ifdef TESTING
/* ToDo: might want to trace a FATAL if integration testing */
#define ASSERT_MSG(subsystem, message, condition) if (!(condition)) {printf("Assert failed: \"%s\" at line %d in file \"%s\"\n", message, __LINE__, __FILE__); fflush(stdout); abort();}
/* we can also use this, which prints of the failed condition as its message */
#define ASSERT_CONDITION(subsystem, condition) if (!(condition)) {printf("Assert failed: \%s\" at line %d in file \%s\"\n", #condition, __LINE__, __FILE__); fflush(stdout); abort();}
#else
#define ASSERT_MSG(subsystem, message, condition) if (!condition) DebugTrace(FATAL, subsystem, __FILE__, __LINE__, "%s", message);
#define ASSERT_CONDITION(subsystem, condition) if (!(condition)) DebugTrace(FATAL, subsystem, __FILE__, __LINE__, "%s", #condition);
#endif
What you would be looking for is an assertion like ASSERT_CONSISTENT(A_x, offsetof(A,x)), placed in a header file. Let me explain why, and what the problem is.
Because the problem exists across translation units, you can only detect the error at link time. That means you need to force the linker to spit out an error. Unfortunately, most cross-translation unit problems are formally of the "no diagnosis needed" kind. The most familiar one is the ODR rule. We can trivially cause ODR violations with such assertions, but you just can't rely on the linker to warn you about them. If you can, the implementation of the ODR can be as simple as
#define ASSERT_CONSISTENT(label, x) class ASSERT_ ## label { char test[x]; };
But if the linker doesn't notice these ODR violations, this will pass by silently. And here lies the problem: the linker really only needs to complain if it can't find something.
With two macro's the problem is solved:
template <int i> class dummy; // needed to differentiate functions
#define ASSERT_DEFINE(label, x) void ASSERT_label(dummy<x>&) { }
#define ASSERT_CHECK(label, x) void (*check)(dummy<x>&) = &ASSERT_label;
You'd need to put the ASSERT_DEFINE macro in a .cpp, and ASSERT_CHECK in its header. If the x value checked isn't the x value defined for that label, you're taking the address of an undefined function. Now, a linker doesn't need to warn about multiple definitions, but it must warn about missing definitions.
BTW, for this particular problem, see Diagnosing Hidden ODR Violations in Visual C++ (and fixing LNK2022)

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.