#define not executing all arguments - c++

I am having trouble with a #define I have made. For some reason it is not checking all the arguments in the statement.
THROW_AND_LOG(Foo::Initialize() && Bar::Initialize() && FooBar::Initialize(), "Something() could not Initialize singletons.");
For some reason it is only initializes Foo and then exits the statement. It does not throw or log.
However
THROW_AND_LOG((Foo::Initialize() && Bar::Initialize() && FooBar::Initialize()), "Something() could not Initialize singletons.");
works fine for some reason. (Wrapped all the checks in brackets).
I am going to move everything on to its own seperate line to fix this as its not the best code in the first place. I am curious however of why it would not execute all statements.
Here is the define:
#define THROW_AND_LOG(x, message) if(!x) { throw std::runtime_error(message); \
LOG::v1::MessageSender messageSender("log"); \
LOGGING_ERROR(messageSender,message);}

After the macro expansion,
if(!x)
transforms to
if(!Foo::Initialize() && Bar::Initialize() && FooBar::Initialize())
Foo::Initialize() presumably returns true, so !Foo::Initialize() is false and other terms are not executed (not mentioning that their meaning has changed to the opposite).

It's not expanding the way you think it is. You want (!(x)) in your macro.

With the macro definition
#define THROW_AND_LOG(x, message) if(!x) { throw std::runtime_error(message); \
LOG::v1::MessageSender messageSender("log"); \
LOGGING_ERROR(messageSender,message);}
the invocation
THROW_AND_LOG(Foo::Initialize() && Bar::Initialize() && FooBar::Initialize(), "Something() could not Initialize singletons.");
yields the condition
if(!Foo::Initialize() && Bar::Initialize() && FooBar::Initialize())
which is equivalent to
if((!Foo::Initialize()) && Bar::Initialize() && FooBar::Initialize())
A good fix is to replace the macro with a function:
void throw_and_log_if(
const bool condition,
const Location& location,
const string& message )
{
LOG::v1::MessageSender messageSender( "log" );
LOGGING_ERROR( messageSender, message ); }
throw std::runtime_error( message );
}
where Location is some class representing file and line number, which you can pick up via the __FILE__ and __LINE__ macros.
I took the liberty of fixing the bug causing logging to not be performed.
A short term easier fix is to use parenthesis around the x in the macro's condition.
If you choose that, then do remember to fix the bug in the macro.

Related

C++ Custom Assert

I am trying to write my own custom assert for my own project. This project will be written with c++11.
The assert must have the following qualities:
It must be kept as an expression and is assignable.
E.g. I should be able to write code like this int x = custom_assert(1/y);
It must be overloaded to accept an assert with a message and without one.
E.g int x = custom_assert(1/y, "Error divide by zero"); This code and the above are both compilable and acceptable.
It must have no side-effects in release mode
E.g. int x = custom_assert(1/y); will become int x = 1/y; in release mode.
And most importantly, it must break at the specific point where the assert was made. Which will make use of __debugbreak() as part of its evaluating expression.
The following is my attempt:
#include <string>
bool DoLog(std::string msg, std::string file, int line); //Prints to std::cerr and returns HALT macro
#if defined(_DEBUG) || defined(DEBUG)
#define HALT true
#define NT_ASSERT_BASE(x, msg) (!(x) && DoLog((msg), __FILE__, __LINE__) && (__debugbreak(),1))
#else
#define HALT false
#define NT_ASSERT_BASE(x,msg) (x)
#endif//debug/release defines
//--- Can't implement these until I can return the expression ---
//#define GET_MACRO(_1,_2,_3,NAME,...) NAME
//#define FOO(...) GET_MACRO(__VA_ARGS__, FOO3, FOO2)(__VA_ARGS__)
#define NT_ASSERT(expression, msg) NT_ASSERT_BASE(expression,msg)
As you can see my custom assert fails on 2 fronts, namely being kept as expression and assignable, and on overloading (Which I cannot implement until I figure out how to keep it as an expression.
All in all, I may be chasing stars and this macro may in fact be impossible to make. (Which I hope isn't the case)
Many thanks.
As far as I can tell, this can't be done in standard C++.
There is no way to get the __debugbreak() into the expanded code and at the same time pass the result of the expression unmodified, because you need the result twice: once for testing it, which will implicitly cast it to bool, and once to return it at the end.
There are two options:
Use gcc's and clang's ({}) construct with auto variable to hold the result. That will exclude MSC++, but I suppose you want that, because __debugbreak() is a MSC++ misfeature.
Give up on requiring the __debugbreak() on the call site, accept having to go one level up when it stops and make the thing as a template function.
A lambda expression will fit slightly better than a template function. It will make the break appear at the macro site, but it will still appear as a separate stack frame in the call stack. It also requires C++11 support (it was published over 5 years ago, but some platforms may not have it).
I don't think you should be mixing the validation with the assignment. From your example, it looks like you want to assign to an integer but an assertion, by nature, is a boolean expression. Further, your example is asserting on the wrong expression. It looks like you want to assert that y is not equal to zero (preventing division by zero), but you are asserting against something that will also be one or false or undefined.
If you are willing to be a bit flexible with your assignment requirements, then we can work around the problem of maintaining the expression and other useful info with some macro magic. Further, we can execute the __debugbreak() at the call site.
#include <iostream>
#include <string>
#include <type_traits>
template<class Fun>
inline bool DoLog(Fun f, std::string message, const char *expression, const char *filename, int line) {
static_assert(std::is_same<bool, decltype(f())>::value, "Predicate must return a bool.");
if (!(f())) {
std::cerr << filename << '#' << line << ": '" << expression << "' is false.";
if (!message.empty()) {
std::cerr << ' ' << message;
}
std::cerr << std::endl;
return false;
}
return true;
}
#if defined(_DEBUG) || defined(DEBUG)
#define HALT true
#define WITH_MESSAGE_(expr, x) [&](){return (expr);}, x, #expr
#define WITHOUT_MESSAGE_(expr) [&](){return (expr);}, std::string{}, #expr
#define PICK_ASSERTION_ARGS_(_1, _2, WHICH_, ...) WHICH_
#define CREATE_ASSERTION_ARGS_(...) PICK_ASSERTION_ARGS_(__VA_ARGS__, WITH_MESSAGE_, WITHOUT_MESSAGE_)(__VA_ARGS__)
#define NT_ASSERT(...) if (!DoLog(CREATE_ASSERTION_ARGS_(__VA_ARGS__), __FILE__, __LINE__)) __debugbreak()
#else
#define HALT false
#define NT_ASSERT(...)
#endif
int main() {
NT_ASSERT(true);
NT_ASSERT(false);
NT_ASSERT(1 == 1, "1 is 1");
NT_ASSERT(1 == 0, "1 is not 0");
return 0;
}
NOTE: The above snippet works on GCC using -std=c++11 (with a placeholder for the __debugbreak() statement). I'm making an assumption that VC++ would work also when it fully supports C++11.

Custom `assert` macro that supports commas and error message

I would like to create a custom version of the assert macro defined in <cassert>, that displays an error message when the assertion fails.
Desired usage:
custom_assert(AClass<T1, T2>::aBoolMethod(), "aBoolMethod must be true");
Flawed test implementations:
#define custom_assert(mCondition, mMessage) ...
// This fails because mCondition may have commas in it
#define custom_assert(..., mMessage)
// Not sure about this either - mMessage may be an expression containing commas
// as well
How can I correctly implement a custom assert that takes a boolean expression (with possible commas) as the first argument and a string expression (with possible commas) as the second argument?
Or is there a way to implement assertions without the use of macros?
You were quite close, what you need to use is simply this:
#define myAssert(message, ...) do { \
if(!(__VA_ARGS__)) { \
/*error code*/ \
} \
} while(0)
The special preprocessor variable __VA_ARGS__ will expand to whatever was passed in the place of the three dots, including all comas.
Note that the preprocessor will not interprete commas in the condition in the very least, it will just paste them as is into the if() statement. Which is precisely what you want if you want to pass templated conditions, as hinted by the comments.
Commas in the message string are not a problem either, since the preprocessor understands about string literals and does not interprete anything within the double quotes.
The straightforward
assert(AClass<T1, T2>::aBoolMethod() && "aBoolMethod must be true");
fails:
error: macro "assert" passed 2 arguments, but takes just 1
but if you add an extra pair of parenthesis around the first argument, it works. Like this:
#include <cassert>
template <typename A, typename B>
struct C {
bool f() { return false; }
};
int main() {
assert((C<int,int>().f()) && "some message, with comma");
// ^ ^
}
Note: it was also pointed out by Adam Rosenfield in a comment.
Perhaps the only benefit over the __VA_ARGS__ approach is that it doesn't dump yet another macro on the user. If you forget the parenthesis, you can get a compile time error, so I see it as a safe solution.
For the sake of completeness, I published a drop-in 2 files assert macro implementation in C++:
#include <pempek_assert.h>
int main()
{
float min = 0.0f;
float max = 1.0f;
float v = 2.0f;
PEMPEK_ASSERT(v > min && v < max,
"invalid value: %f, must be between %f and %f", v, min, max);
return 0;
}
Will prompt you with:
Assertion 'v > min && v < max' failed (DEBUG)
in file e.cpp, line 8
function: int main()
with message: invalid value: 2.000000, must be between 0.000000 and 1.000000
Press (I)gnore / Ignore (F)orever / Ignore (A)ll / (D)ebug / A(b)ort:
Where
(I)gnore: ignore the current assertion
Ignore (F)orever: remember the file and line where the assertion fired and
ignore it for the remaining execution of the program
Ignore (A)ll: ignore all remaining assertions (all files and lines)
(D)ebug: break into the debugger if attached, otherwise abort() (on Windows,
the system will prompt the user to attach a debugger)
A(b)ort: call abort() immediately
You can find out more about it there:
blog post
GitHub project
Hope that helps.
I'm not entirely sure what you mean by a "boolean expression with commas." Simply wrapping macro expansions in commas (as seen in the samples below) protects against parse errors if you happen to use the default comma operator in your conditions, but the default comma operator does not do the same thing as &&. If you mean you want something like:
my_assert(condition1, condition2, message1, message2);
You're out of luck. How should any API tell where the conditions stop and the messages start. Just use &&. You can use the same tricks below for handling the message portion to also create a my_condition_set macro that allows you to write something like:
my_asssert(my_condition_set(condition1, condition2), message1, message2);
Getting to the message part, which is the tricky part and the most useful part that the standard assert macros tend to lack, the trick will come down to either using a custom message output type that overrides operator, (the comma operator) or to use a variadic template.
The macro uses variadic macro support and some tricks to deal with commas. Note that none of the code I'm posting here is tested directly; it's all from memory from custom assert macros I've written in the past.
The version using comma operator overloading, which works in C++98 compilers:
struct logger {
template <typename T>
logger& operator,(const T& value) {
std::cerr << value;
return *this;
}
};
#define my_assert(condition, ...) do{ \
if (!(condition)) { \
(logger() , __VA_ARGS__); \
std::terminate(); \
} \
}while(false)
The logger() expression creates a new instance of the logger type. The list of arguments from __VA_ARGS__ is then pasted with commas separating each. These commas each invoke the comma operator left-to-right, which forwards the expression on to std::cerr. I usually use a custom log stream that handles writing to files, cerr, Windows' OutputDebugStringA, or whatever.
Using variadic templates in a C++11 compiler, this would be more like:
template <typename ...Ts>
void logger(Ts&&... argv) {
std::cerr << your_string_format_function(argv...);
}
void logger(const char* fmt) {
std::cerr << fmt;
}
void logger() {}
#define my_assert(condition, ...) do{ \
if (!(condition)) { \
logger(__VA_ARGS__); \
std::terminate(); \
} \
}while(false)
You'd need a format string function that actually works with variadic arguments or write an adapter for something like boost::format.
You could also use printf if you don't mind the lack of type-safety.

C++ macro expansion to function body

I would like to be able to write a macro CONDITIONALFUNCTION so that
CONDITIONALFUNCTION( FunctionName )
{
ConditionalExpression()
}
expands to
bool FunctionName( const Arguments& args )
{
return ConditionalExpression();
}
Is this even possible?
The closest I can find on SO is this thread:
Possible to define a function-like macro with a variable body?
except unlike in that thread, I have the additional requirement that the "body" within the braces is not a complete valid C++ statement, but rather an expression to be wrapped (effectively) in an 'if' statement.
Please assume I already know this may be impossible, and is almost surely stupid and evil :)
I'm going to assume you've got a good reason for using macros in the first place...
It's not possible with the syntax you've given with the question.
The closest workable macro syntax is:
#define CONDITIONALEXPRESSION(f, c) \
bool f( const Arguments& args ) \
{ return c; }
CONDITIONALEXPRESSION(FunctionName, ConditionalExpression())
This will expand to the same as the expanded function in the question
Is there any reason why the function body must be defined in the macro? In Microsoft C++, macros like ASSERT() define the actual function separately and then just reference it from the macro.
So the function is always defined but the macro is either equal to calling the function or nothing at all.
Aside from that, for C++ I'd probably use an inline function.
je4d already provided one alternative. I over some other variation:
#define CONDITIONALEXPRESSION(f) \
bool f( const Arguments& args )
#define CONDITIONALRETURN(c) \
return (c)
CONDITIONALEXPRESSION(FunctionName)
{
CONDITIONALRETURN(ConditionalExpression())
}

Have macro 'return' a value

I'm using a macro and I think it works fine -
#define CStrNullLastNL(str) {char* nl=strrchr(str,'\n'); if(nl){*nl=0;}}
So it works to zero out the last newline in a string, really its used to chop off the linebreak when it gets left on by fgets.
So, I'm wondering if I can "return" a value from the macro, so it can be called like
func( CStrNullLastNL( cstr ) ) ;
Or will I have to write a function
For a macro to "return a value", the macro itself has to be an expression. Your macro is a statement block, which cannot evaluate to an expression.
You really ought to write an inline function. It will be just as fast and far more maintainable.
#define CStrNullLastNL(str) ({ \
char* nl=strrchr(str,'\n');\
if(nl){*nl=0;} \
nl; \
})
should work.
Edit: ... in GCC.
Macro's don't return values. Macros tell the preprocessor to replace whatever is after the #define with whatever is after the thing after the #define. The result has to be valid C++.
What you're asking for is how to make the following valid:
func( {char* nl=strrchr(str,'\n'); if(nl){*nl=0;}} );
I can't think of a good way to turn that into something valid, other than just making it a real function call. In this case, I'm not sure why a macro would be better than an inline function. That's seems to be what you're really asking for.
If you really want to do this, get a compiler that supports C++0x style lambdas:
#define CStrNullLastNL(str) [](char *blah) {char* nl=strrchr(blah,'\n'); if(nl){*nl=0;} return blah;}(str)
Although since CStrNullLastNL is basically a function you should probably rewrite it as a function.
Can you use the comma operator? Simplified example:
#define SomeMacro(A) ( DoWork(A), Permute(A) )
Here B=SomeMacro(A) "returns" the result of Permute(A) and assigns it to "B".
I gave +1 to Mike because he's 100% right, but if you want to implement this as a macro,
char *CStrNullLastNL_nl; // "private" global variable
#define nl ::CStrNullLastNL_nl // "locally" redeclare it
#define CStrNullLastNL( str ) ( \
( nl = strrchr( str, '\n') ), /* find newline if any */ \
nl && ( *nl = 0 ), /* if found, null out */ \
(char*) nl /* cast to rvalue and "return" */ \
OR nl? str : NULL /* return input or NULL or whatever you like */
)
#undef nl // done with local usage
If you don't have a strict requirement to use only macro, you can do something like this (real life example):
#define Q_XCB_SEND_EVENT_ALIGNED(T) \
q_xcb_send_event_aligned<T>()
template<typename T> inline
T q_xcb_send_event_aligned()
{
union {
T event;
char padding[32];
} event;
memset(&event, 0, sizeof(event));
return event.event;
}
And then use it in your code like this:
auto event = Q_XCB_SEND_EVENT_ALIGNED(xcb_unmap_notify_event_t);
Returning a value is what inline functions are for. And quite often, said inline functions are better suited to tasks than macros, which are very dangerous and have no type safetly.
to return value from macro:
bool my_function(int a) {
if (a > 100)return true;
return false;
}
bool val = my_function(200);
#define my_macro(ret_val,a){\
if(a > 100 ) ret_val = true;\
ret_val = false;\
}
bool val; my_macro(val, 200);

How can I assert() without using abort()?

If I use assert() and the assertion fails then assert() will call abort(), ending the running program abruptly. I can't afford that in my production code. Is there a way to assert in runtime yet be able to catch failed assertions so I have the chance to handle them gracefully?
Yes, as a matter of fact there is. You will need to write a custom assert function yourself, as C++'s assert() is exactly C's assert(), with the abort() "feature" bundled in. Fortunately, this is surprisingly straightforward.
Assert.hh
template <typename X, typename A>
inline void Assert(A assertion)
{
if( !assertion ) throw X();
}
The above function will throw an exception if a predicate doesn't hold. You will then have the chance to catch the exception. If you don't catch the exception, terminate() will be called, which will end the program similarly to abort().
You may wonder what about optimizing away the assertion when we're building for production. In this case, you can define constants that will signify that you're building for production and then refer to the constant when you Assert().
debug.hh
#ifdef NDEBUG
const bool CHECK_WRONG = false;
#else
const bool CHECK_WRONG = true;
#endif
main.cc
#include<iostream>
struct Wrong { };
int main()
{
try {
Assert<Wrong>(!CHECK_WRONG || 2 + 2 == 5);
std::cout << "I can go to sleep now.\n";
}
catch( Wrong e ) {
std::cerr << "Someone is wrong on the internet!\n";
}
return 0;
}
If CHECK_WRONG is a constant then the call to Assert() will be compiled away in production, even if the assertion is not a constant expression. There is a slight disadvantage in that by referring to CHECK_WRONG we type a little more. But in exchange we gain an advantage in that we can classify various groups of assertions and enable and disable each of them as we see fit. So, for example we could define a group of assertions that we want enabled even in production code, and then define a group of assertions that we only want to see in development builds.
The Assert() function is equivalent to typing
if( !assertion ) throw X();
but it clearly indicates the intent of the programmer: make an assertion. Assertions are also easier to grep for with this approach, just like plain assert()s.
For more details on this technique see Bjarne Stroustrup's The C++ Programming Language 3e, section 24.3.7.2.
glib's error reporting functions take the approach of continuing after an assert. glib is the underlying platform independence library that Gnome (via GTK) uses. Here's a macro that checks a precondition and prints a stack trace if the precondition fails.
#define RETURN_IF_FAIL(expr) do { \
if (!(expr)) \
{ \
fprintf(stderr, \
"file %s: line %d (%s): precondition `%s' failed.", \
__FILE__, \
__LINE__, \
__PRETTY_FUNCTION__, \
#expr); \
print_stack_trace(2); \
return; \
}; } while(0)
#define RETURN_VAL_IF_FAIL(expr, val) do { \
if (!(expr)) \
{ \
fprintf(stderr, \
"file %s: line %d (%s): precondition `%s' failed.", \
__FILE__, \
__LINE__, \
__PRETTY_FUNCTION__, \
#expr); \
print_stack_trace(2); \
return val; \
}; } while(0)
Here's the function that prints the stack trace, written for an environment that uses the gnu toolchain (gcc):
void print_stack_trace(int fd)
{
void *array[256];
size_t size;
size = backtrace (array, 256);
backtrace_symbols_fd(array, size, fd);
}
This is how you'd use the macros:
char *doSomething(char *ptr)
{
RETURN_VAL_IF_FAIL(ptr != NULL, NULL); // same as assert(ptr != NULL), but returns NULL if it fails.
if( ptr != NULL ) // Necessary if you want to define the macro only for debug builds
{
...
}
return ptr;
}
void doSomethingElse(char *ptr)
{
RETURN_IF_FAIL(ptr != NULL);
}
Asserts in C/C++ only run in debug builds. So this won't happen at runtime. In general asserts should mark things that if they happen indicate a bug, and generally show assumptions in your code etc.
If you want to have code that checks for errors at runtime (in release) you should probably use exceptions rather than asserts as these are what they are designed to do. Your answer basically wraps an exception thrower in assert syntax. While this will work, there is no particular advantage to this that I can see over just throwing the exception in the first place.
Here's what I have my in "assert.h" (Mac OS 10.4):
#define assert(e) ((void) ((e) ? 0 : __assert (#e, __FILE__, __LINE__)))
#define __assert(e, file, line) ((void)printf ("%s:%u: failed assertion `%s'\n", file, line, e), abort(), 0)
Based on that, replace the call to abort() by a throw( exception ). And instead of printf you can format the string into the exception's error message. In the end, you get something like this:
#define assert(e) ((void) ((e) ? 0 : my_assert (#e, __FILE__, __LINE__)))
#define my_assert( e, file, line ) ( throw std::runtime_error(\
std::string(file:)+boost::lexical_cast<std::string>(line)+": failed assertion "+e))
I haven't tried to compile it, but you get the meaning.
Note: you'll need to make sure that the "exception" header is always included, as well as boost's (if you decide to use it for formatting the error message). But you can also make "my_assert" a function and only declare its prototype. Something like:
void my_assert( const char* e, const char* file, int line);
And implement it somewhere where you can freely include all the headers you require.
Wrap it in some #ifdef DEBUG if you need it, or not if you always want to run those checks.
If you want to throw a character string with information about the assertion:
http://xll8.codeplex.com/SourceControl/latest#xll/ensure.h
_set_error_mode(_OUT_TO_MSGBOX);
believe me, this function can help you.