Add custom messages in assert? - c++

Is there a way to add or edit the message thrown by assert? I'd like to use something like
assert(a == b, "A must be equal to B");
Then, the compiler adds line, time and so on...
Is it possible?

A hack I've seen around is to use the && operator. Since a pointer "is true" if it's non-null, you can do the following without altering the condition:
assert(a == b && "A is not equal to B");
Since assert shows the condition that failed, it will display your message too. If it's not enough, you can write your own myAssert function or macro that will display whatever you want.

Another option is to reverse the operands and use the comma operator. You need extra parentheses so the comma isn't treated as a delimiter between the arguments:
assert(("A must be equal to B", a == b));
(this was copied from above comments, for better visibility)

Here's my version of assert macro, which accepts the message and prints everything out in a clear way:
#include <iostream>
#ifndef NDEBUG
# define M_Assert(Expr, Msg) \
__M_Assert(#Expr, Expr, __FILE__, __LINE__, Msg)
#else
# define M_Assert(Expr, Msg) ;
#endif
void __M_Assert(const char* expr_str, bool expr, const char* file, int line, const char* msg)
{
if (!expr)
{
std::cerr << "Assert failed:\t" << msg << "\n"
<< "Expected:\t" << expr_str << "\n"
<< "Source:\t\t" << file << ", line " << line << "\n";
abort();
}
}
Now, you can use this
M_Assert(ptr != nullptr, "MyFunction: requires non-null argument");
And in case of failure you will get a message like this:
Assert failed:  MyFunction: requires non-null argument
Expected: ptr != nullptr
Source: C:\MyProject\src.cpp, line 22
Nice and clean, feel free to use it in your code =)

BOOST_ASSERT_MSG(expre, msg)
http://www.boost.org/doc/libs/1_51_0/libs/utility/assert.html
You could either use that directly or copy Boost's code. Also note Boost assert is header only, so you could just grab that single file if you didn't want to install all of Boost.

As zneak's answer convolutes the code somewhat, a better approach is to merely comment the string text you're talking about. ie.:
assert(a == b); // A must be equal to B
Since the reader of the assert error will look up the file and line anyway from the error message, they will see the full explanation here.
Because, at the end of the day, this:
assert(number_of_frames != 0); // Has frames to update
reads better than this:
assert(number_of_frames != 0 && "Has frames to update");
in terms of human parsing of code ie. readability. Also not a language hack.

assert is a macro/function combination. you can define your own macro/function, using __FILE__, __BASE_FILE__, __LINE__ etc, with your own function that takes a custom message

If the assert is done within a class, an alternative approach is to call a static predicate function with a self-describing name. If the assertion fails, the message will already contain the predicate's pretty and self-describing name.
E.g.:
static bool arguments_must_be_ordered(int a, int b) {return a <= b;}
void foo(int a, int b)
{
assert(arguments_must_be_ordered(a, b));
// ...
}
You may even want to make that predicate function public so that the class' user can verify the precondition themselves.
Even if assert is not disabled for release builds, the compiler will likely inline the predicate if it's fairly trivial.
The same approach can be used for complex if conditions needing a comment. Instead of a comment, just call a self-describing predicate function.

You could also just write your own custom assert function. A very simple example:
bool print_if_false(const bool assertion, const char* msg) {
if(!assertion) {
// endl to flush
std::cout << msg << std::endl;
}
return assertion;
}
int main()
{
int i = 0;
int j = 1;
assert(print_if_false(i == j, "i and j should be equal"));
return 0;
}
play with the code.
The assertion reads Assertion print_if_false(i == j, "i and j should be equal").

int x=10, y=25;
assert(x > y); // Add message along with this assert
Option 1) Since fprintf returns number of characters printed so we can or assert expression with !fprintf. Using stderr here since this is an error message
assert((x > y) || !fprintf(stderr, "Error: x %d is expected to be greater than y %d \n", x, y));
We can wrap this inside a macro for convinient use.
// Define macro over assert
#define assert_msg(cond, fmt, ...) assert( cond || !fprintf(stderr, fmt, ##__VA_ARGS__))
// Use above macro
assert_msg(x > y, "Error: x %d is expected to be greater than y %d \n", x, y);
Option 2) Define error message wrapped inside lambda.
auto err = [x, y] { fprintf(stderr, "Error: x %d should be greater than y %d \n", x, y); return false; };
assert((x > y) || err()); // Assert calls lambda func only when condition fails
Here is the dumped message.
Error: x 10 should be greater than y 25
File.cpp:10: int main(): Assertion `(x > y) || err()' failed.
Option 3) Or we can refine above solution to do it in one line with help of immediately invoked lambda
assert((x > y) || ([x, y] { fprintf(stderr, "Error: x %d is expected to be greater than y %d \n", x, y); return false; }()));

For vc, add following code in assert.h,
#define assert2(_Expression, _Msg) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Msg), _CRT_WIDE(__FILE__), __LINE__), 0) )

Related

How to get a value of __LINE__ of another function (before calling that function)?

For the currently existing test framework I need to pass (during the first-most call) to the function a line number of a fragment inside of that function. Something like this:
#include <stdio.h>
void func(int line_num)
{
#define LINE_NUM (__LINE__ + 1)
if(line_num == __LINE__) // Check the passed arg against the current line.
printf("OK");
else
printf("FAIL");
}
int main(void)
{
func(LINE_NUM); // Pass to the func the line number inside of that func.
return 0;
}
(this is a minimalistic version of a more complex functionality).
As is the sample code prints "FAIL".
If I pass an absolute value 5, e.g. func(5) then it prints "OK". I don't like the absolute value 5 because if I add one more line in front of the func definition then the absolute value will need a correction.
Instead of #define LINE_NUM (__LINE__ + 1) I also tried the following:
1.
#define VALUE_OF(x) x
#define LINE_NUM (VALUE_OF(__LINE__) + 1)
2.
#define VAL(a,x) a##x
#define LOG_LINE() ( VAL( /*Nothing*/,__LINE__) + 1)
3.
#define VALUE_OF2(x) x
#define VALUE_OF(x) VALUE_OF2(x)
#define LINE_NUM (VALUE_OF(__LINE__) + 1)
I'm using:
gcc --version
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
In my sample code the value that func() gets is 14 (the call site line number + 1).
You cannot get the preprocessor to expand __LINE__ in a macro definition. That's not the way the preprocessor works.
But you can create global constants.
#include <stdio.h>
static const int func_line_num = __LINE__ + 3;
void func(int line_num)
{
if(line_num == __LINE__) // Check the passed arg against the current line.
printf("OK");
else
printf("FAIL");
}
int main(void)
{
func(func_line_num); // Pass to the func the line number inside of that func.
return 0;
}
If you don't like static const int, for whatever reason, you could use an enum:
enum { FUNC_LINE_NUM = __LINE__ + 3 };
Unfortunately, whether you use a global constant or an enum, you have to put the definition at file scope, which might make it somewhat distant from the use point. However, it is not immediately apparent why the precise line number of the test needs to be used, rather than (for example) the first line of the function or even any integer guaranteed to be unique:
#include <stdio.h>
// As long as all uses of __LINE__ are on different lines, the
// resulting values will be different, at least within this file.
enum { FUNC_LINE_NUM = __LINE__ };
void func(int line_num)
{
if(line_num == FILE_LINE_NUM) // Check the passed arg against the appropriate constant.
printf("OK");
else
printf("FAIL");
}
int main(void)
{
func(func_line_num); // Pass to the func the line number inside of that func.
return 0;
}
After #rici 's great answer and comments the closest thing to what I need is the following:
#include <stdio.h>
#define LINE_NUM_TESTER() \
enum { LINE_NUM = __LINE__ }; \
\
void line_num_tester(int line_num) \
{ \
if(line_num == __LINE__) \
printf("OK\n"); \
else \
printf("FAIL. line_num: %d, __LINE__: %d.\n", line_num, __LINE__); \
}
LINE_NUM_TESTER()
int main(void)
{
line_num_tester(LINE_NUM);
return 0;
}

Is this the right way to use recursion?

Given strings s and t compute recursively, if t is contained in s return true.
Example: bool find("Names Richard", "Richard") == true;
I have written the code below, but I'm not sure if its the right way to use recursion in C++; I just learned recursion today in class.
#include <iostream>
using namespace std;
bool find(string s, string t)
{
if (s.empty() || t.empty())
return false;
int find = static_cast<int>(s.find(t));
if (find > 0)
return true;
}
int main()
{
bool b = find("Mississippi", "sip");
string s;
if (b == 1) s = "true";
else
s = "false";
cout << s;
}
If anyone find an error in my code, please tell me so I can fix it or where I can learn/read more about this topic. I need to get ready for a test on recursion on this Wednesday.
The question has changed since I wrote my answer.
My comments are on the code that looked like this (and could recurse)...
#include <iostream>
using namespace std;
bool find(string s, string t)
{
if (s.empty() || t.empty())
return false;
string start = s.substr(0, 2);
if (start == t && find(s.substr(3), t));
return true;
}
int main()
{
bool b = find("Mississippi", "sip");
string s;
if (b == 1) s = "true";
else
s = "false";
cout << s;
}
Watch out for this:
if (start == t && find(s.substr(3), t));
return true;
This does not do what you think it does.
The ; at the end of the if-statement leaves an empty body. Your find() function will return true regardless of the outcome of that test.
I recommend you turn up the warning levels on your compiler to catch this kind of issue before you have to debug it.
As an aside, I find using braces around every code-block, even one-line blocks, helps me avoid this kind of mistake.
There are other errors in your code, too. Removing the magic numbers 2 and 3 from find() will encourage you to think about what they represent and point you on the right path.
How would you expect start == t && find(s.substr(3), t) to work? If you can express an algorithm in plain English (or your native tongue), you have a much higher chance of being able to express it in C++.
Additionally, I recommend adding test cases that should return false (such as find("satsuma", "onion")) to ensure that your code works as well as calls that should return true.
The last piece of advice is stylistic, laying your code out like this will make the boolean expression that you are testing more obvious without resorting to a temporary and comparing to 1:
int main()
{
std::string s;
if (find("Mississippi", "sip"))
{
s = "true";
}
else
{
s = "false";
}
std::cout << s << std::endl;
}
Good luck with your class!
Your recursive function needs 2 things:
Definite conditions of failure and success (may be more than 1)
a call of itself to process a simpler version of the problem (getting closer to the answer).
Here's a quick analysis:
bool find(string s, string t)
{
if (s.empty() || t.empty()) //definite condition of failure. Good
return false;
string start = s.substr(0, 2);
if (start == t && find(s.substr(3), t)); //mixed up definition of success and recursive call
return true;
}
Try this instead:
bool find(string s, string t)
{
if (s.empty() || t.empty()) //definite condition of failure. Done!
return false;
string start = s.substr(0, 2);
if (start == t) //definite condition of success. Done!
return true;
else
return find(s.substr(3), t) //simply the problem and return whatever it finds
}
You're on the right lines - so long as the function calls itself you can say that it's recursive - but even the most simple testing should tell you that your code doesn't work correctly. Change "sip" to "sipx", for example, and it still outputs true. Have you compiled and run this program? Have you tested it with various different inputs?
You are not using recursion. Using std::string::find in your function feels like cheating (this will most likely not earn points).
The only reasonable interpretation of the task is: Check if t is an infix of s without using loops or string functions.
Let's look at the trivial case: Epsilon (the empty word) is an infix of ever word, so if t.empty() holds, you must return true.
Otherwise you have two choices to make:
t might be a prefix of s which is simple to check using recursion; simply check if the first character of t equals the first character of s and call isPrefix with the remainder of the strings. If this returns true, you return true.
Otherwise you pop the first character of s (and not of t) and proceed recursively (calling find this time).
If you follow this recipe (which btw. is easier to implement with char const* than with std::string if you ask me) you get a recursive function that only uses conditionals and no library support.
Note: this is not at all the most efficient implementation, but you didn't ask for efficiency but for a recursive function.

Assigning and Conditional Testing Simultaneously in C++

I have three functions that return integer error codes, e.g.
int my_function_1(const int my_int_param);
int my_function_2(const int my_int_param);
int my_function_3(const int my_int_param);
I want to assign and test for error at the same time for brevity. Will the following work and be portable?
int error=0;
...
if ( error ||
(error = my_function_1(val1) ||
error = my_function_2(val2) ||
error = my_function_3(val3)) ) {
std::cout << "AN ERROR OCCURRED!!!" << std::endl;
}
Thanks!
Why not throw an exception?
void my_function_1(const int my_int_param);
void my_function_2(const int my_int_param);
void my_function_3(const int my_int_param);
try {
my_function_1(...);
my_function_2(...);
my_function_3(...);
} catch(std::exception& e) {
std::cout << "An error occurred! It is " << e.what() << "\n";
}
I don't understand why you have the error && at the beginning of the function, but the rest should do what you want. Short circuit evaluation of the || operators is guaranteed by the standard. I would consider it bad style though.
Edit: Based on your comment, you would need to replace error && with error ||. I will also add that this is a good reason to use exceptions rather than error codes, it makes your code so much easier to read.
error is initialized to 0.So the && will always evaluates to false. So other parts of the if condition are never evaluated. So this code will not work. If you remove the && condition the code should work portably as the standard guarantees the order of the evaluation in this case.
Yes, after the minor change of && with || it will work. But it's just too confusing (using = in tests is confusing) with not much benefit.
You could go for exception line another poster suggested, or simply put your checked code inside function and do like below.
int checked(){
int error = 0;
error = my_function_1(val1); if (error) return error;
error = my_function_2(val1); if (error) return error;
error = my_function_3(val1); if (error) return error;
return error;
}
I believe any programmer will easily understand what is done here.

Using local variables vs checking against function return directly

I have a function definition, where i call multiple functions. Even if one of the function fails i need to go ahead and call the rest of the functions and finally return a single error saying whether any of the function call failed. The approach which i had followed was
int function foo()
{
int res, res1, res2, res3;
res1 = function1();
res2 = function2();
res3 = function3();
if (res1 == -1 || res2 == -1 || res3 == -1)
{
res = -1;
}
return res;
}
The possible another approach is
int function foo()
{
int res;
if (function1() == -1)
{
res = -1;
}
if (function2() == -1)
{
res = -1;
}
if (function3() == -1)
{
res = -1;
}
return res;
}
Which is a better approach?
Thanks in advance.
No difference at all, both will be optimized to same machine code. Preference, maintainability, and that depends on team guidelines, preferences.
First priority, make the code correct. That's more important than readability and optimization.
That means you need to consider what the function should return in the case where the functions it calls all succeed.
Many of the answers given to this question change the result returned or might return a failure indication if the 'sub-functions' all succeed. you need to take care not to do this.
Personally, I think the overall form of your first option is pretty good - it makes clear that the 3 sub-functions are called regardless of whether one or more of them fail. The one problem is that it returns an indeterminate result if all those functions succeed.
Be wary of answers that use bitwise-or to combine results - there are at least 2 potential problems:
as John Marshall pointed out in several comments, the order of evaluation is indeterminate. This means that if you simply string the function calls with bitwise-or the functions may be called in any order. This might not be a problem if there are no ordering dependencies between the functions, but usually there are - especially if you don't care about the returned value except as a s success/fail indicator (if you aren't using the return value, then the only reason to call the function is for its side effects)
If the functions can return positive, non-zero values when they succeed, then testing for failure becomes a bit trickier than just checking if the results or'ed together are non-zero.
Given these two potential problems, I think there's little reason to try to do anything much fancier than option 1 (or your second option) - just make sure you set res to a success value (0?) for the situation where none of the sub-functions fail.
What about:
int foo ()
{
bool failed = false;
failed |= (function1() != 0);
failed |= (function2() != 0);
failed |= (function3() != 0);
return failed? -1 : 0;
}
You could also collapse the three calls into a single expression and omit the failed variable altogether (at the expense of readability):
int foo ()
{
return ((function1() != 0) | (function2() !=0 ) | (function3() != 0))? -1 : 0;
}
I like the first approach when function1 function2 and function3 have the same signature because I can put them in a function pointer table and loop over the entries, which makes adding function4 alot easier.
If you can define any precise convention about return values you can simply use bitwise or:
int foo() {
if (function1() | function2() | function3())
return -1;
else
return 0;
}
I like the second approach better. If you want one-liners, you can do something like...
char success = 1;
success &= (foo() == desired_result_1);
success &= (bar() == desired_result_2);
etc.
The 2nd is a "better" approach. However, I'd go more without the needless carrying around of an indicator variable:
if( function2() == -1 ){
return -1;
}
Suggestion: (no magic numbers)
I'd also not use "magic numbers" like you've used it. Instead:
if( check_fail( function2() ) ){
return FAILED;
}
more clearly illustrated what you're thinking. Intent is easier to maintain. Magic numbers can sometimes wind up hurting you. For instance, I've known financial guys who couldn't understand why a transaction costing "$-1.00" caused their application to behave abnormally.
In the first form you're not checking the status until all 3 calls are completed. I think this signals your intent the clearest. The second form more closely resembles the more usual case, where you return early if an error is detected.
It's a subtle thing either way. You shouldn't be asking us strangers on the internet, you should be asking the rest of your team, because they're the ones who will have to live with it.
You use bitwise operators to make a 'neat' variant that doesn't need temp variables and has other fancyness too(with the more advanced operators): return func1()|func2();(this is the same as using logical or, ||). However, if you require checking a specific function in the callee, you can create a bitset: return func1() << 1 | func2(); (this assumes that they return 1 or zero)
I'd vote for the second one as well.
This question reminded me of something similar I do in one of my projects for form validation.
I pass in a reference to an empty string. With each condition I want to check, I either add a line of text to the string, or I don't. If after every test the string is still empty, then there were no errors, and I continue processing the form. Otherwise, I print the string as a message box (which describes the problems), and ask the user to fix the errors.
In this case I don't really care what the errors are, just that there are errors. Oh, and as a bonus, my validation code documents itself a bit because the errors that the user sees are right there.
Use local variable if you need to reuse the result somewhere. Else, call and compare.
int foo() {
return function1() | function2() | function3();
}
Yet another option: pass a pointer to the status variable to each function and have the function set it only if there is an error.
void function1(int *res)
{
bool error_flag = false;
// do work
if (error_flag && (res != NULL)
{
*res = ERROR;
}
}
// similar for function2, function3, ...
int foo()
{
int res = OK;
function1(&res);
function2(&res);
function3(&res);
return res;
}
Since all 3 functions always have to get called first and only then you care about the result, I would go for the first solution, because the order of the statements reflects this. Seems more clear to me. Also, I generally don't like functions that do more than just return a value (i.e. that have side effects) in if-clauses, but that's a personal preference.
This sounds like a job for the abundant Perl idiom "<try something> || die()".
int foo() {
int retVal = 0;
function1() != -1 || retval = -1;
function2() != -1 || retval = -1;
function3() != -1 || retval = -1;
// ...
return retVal;
}
I write it this way:
int foo()
{
int iReturn = 0;
int res1 = function1();
if (res1 == -1)
{
return iReturn;
}
int res2 = function2();
if (res2 == -1)
{
return iReturn;
}
int res3 = function3();
if (res3 == -1)
{
return iReturn;
}
return res;
}
As a coding rule, you should declare your variables as close to the place where it is used.
It is good to use intermediate variable like your res1, res2, res3.
But choose a good name so as you intent is clear when you get the value from the function.
And be careful, in the example you've given us, you never assigned the int res; that may be returned when success. The coding rule is to initialize your variable as soon as you can.
So you should also initialize your res1 res2 res3 immidiatbly.
Returning an uninitialized value leads to undefined behaviour.
I've seen code like this before which might be a little cleaner:
bool result = true;
result = function1() == -1 && result;
result = function2() == -1 && result;
result = function3() == -1 && result;
return result?-1:0;
Edit: forgot about short circuiting.

Pass variable "name" in C++

I currently use the following template simply as a way to check for NULL pointer and if NULL then print out an error message to a log file and then return false.
template< typename T >
static bool isnull(T * t, std::string name = "")
{
_ASSERTE( t != 0 );
if( !t )
{
if( !(name.length()) ) name = "pointer";
PANTHEIOS_TRACE_ERROR(name + " is NULL");
return false;
}
return true;
}
I currently call this as follows:
if( !(isnull(dim, BOOST_STRINGIZE(dim))) ) return false;
If you notice I need to pass in the "name" of the pointer-variable that I want to print to the log file, as the 2nd parameter. I am currently using BOOST_STRINGIZE that simply converts any text inside the parentheses to a string.
The following are the disadvantages of my template implementation (for my usage at least)
Anyone could pass in anything as parameter to BOOST_STRINGIZE to print out in log file - since the 2 parameters are not related in anyway - so I would not necessarily see the "variable name" that is actually NULL
We have to remember to pass in the 2nd parameter, else useless.
Is there anyway I can have the "name" of that 1st variable be automatically determined, so that I can omit passing it in, as the 2nd parameter, with every call?
You could put it all in one macro:
#define IS_NULL(name_) isnull(name_, #name_)
Note that BOOST_STRINGIZE expands its argument if its a macro, which may or may not be what you want:
#define X(x_) std::cout << BOOST_STRINGIZE(x_) << " = " << x_ << std::endl;
X(NULL); // prints: "0 = 0"
The only way to do anything lexically like this is with macros. If you always want the correct printout, your best option is to wrap the whole statement in a macro:
//if( !(isnull(dim, BOOST_STRINGIZE(dim))) ) return false;
#define ISNULL(a) isnull((a), #a)
if (!ISNULL(dim)) return false;
Note that, as always, macros have a number of disadvantages associated with them.
Sure, why not:
#define new_isnull(x) isnull(x, BOOST_STRINGIZE(x))