Understanding macro code statement with lambda and __attribute__ - c++

My program(C++) is defining a macro for throw statements. It is something like:
#define FOO_THROW(some-exception-type, some-error-message) \
do \
{ \
[&]() __attribute__((cold, noinline)) \
{ \
using exception_type = some-exception-type; \
std::ostringstream ss; \
ss << some-error-message << ""; \
throw exception_type(ss.str()); \
} \
(); \
} \
while (0);
Then, it is getting called in the program, something like:
FOO_THROW(std::runtime_error, "error specfic message here")
I can see that we use do...while(0) structure with the macro, what I want to understand is the use of lambda and __attribute__ here, can someone explain that in simple words?
Basically, my focus is what is the need of lambda function here, when it can be done without it, is there can be any specific advantage of it here?
I am a beginner in C++, so any hint in the right direction will do as well!

do...while(0) allows the macro to by called with semicolon at the end, i.e. macro(x,y,z); (note the semicolon at the end), that's an old trick back from C, you can look it up separately.
As for the rest... it defines a lambda (immediate function object) capturing everything by reference (not sure why) that throws exception of a given type with a given message and calls it immediately, effectively throwing an exception.
The attributes signify the lambda is unlikely to be called (cold) and prevent from inlining (noinline), see: https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Function-Attributes.html

Related

How to avoid re-declare variables with C++ Macros

I want to write a simple Macro function. Because this macro is used in many places by different normal c++ functions, I encountered a variable scope issue. I would like to know if there is a quick way to solve it? Thank you very much.
As you can see in the attached code, depending on whether the macro is called in the function for the first time or not, I want to either declare or reuse the variable ptrCandidate. Note the variable scope is in the function, not in the file or translation unit. In other words, every time the macro is invoked in a new function for the 1st time, I want the top macro. And within the same function, if the macro is invoked again, I want the bottom macro.
#define EXPECT_MY_CLASS_EQ(expectedStr, candidateStr) \
auto ptrCandidate = parseAndGetPtr(candidateStr); \
doWork(ptrCandidate); \
EXPECT_EQ(expectedStr, convertToString(ptrCandidate));
#define EXPECT_MY_CLASS_EQ(expectedStr, candidateStr) \
ptrCandidate = parseAndGetPtr(candidateStr); \
doWork(ptrCandidate); \
EXPECT_EQ(expectedStr, convertToString(ptrCandidate));
void foo(){
EXPECT_MY_CLASS_EQ("123","abcd")
}
void bar(){
EXPECT_MY_CLASS_EQ("111","aabb")
EXPECT_MY_CLASS_EQ("222","ccdd")
}
void foo(){
auto ptrCandidate = parseAndGetPtr("abcd");
doWork(ptrCandidate);
EXPECT_EQ("123", convertToString(ptrCandidate));
}
void bar(){
auto ptrCandidate = parseAndGetPtr("aabb");
doWork(ptrCandidate);
EXPECT_EQ("111", convertToString(ptrCandidate));
/* auto */ ptrCandidate = parseAndGetPtr("ccdd");
doWork(ptrCandidate);
EXPECT_EQ("222", convertToString(ptrCandidate));
}
As shown in another answer, you don't need a macro in this case.
Generally speaking though, you can avoid re-definitions of variable names by the following means:
Use of __LINE__ preprocessor symbol (or __COUNTER__, though IIRC that's not standard). Note that creating a variable name with the preprocessor requires two levels of indirection (replace VARIABLE in the link with __LINE__).
A do { /* code */ } while(0) ... which is AFAIK the most common way to write macros that are more than just a simple expression.
A lambda which is immediately executed:
([](auto var) { /* code using var */ })(initExpressionForVar())
Note that each of these approaches actually creates a new variable each time, so is semantically different from your approach with two separate macros! This is especially important if the type of the (assigned) variable has a non-default assignment operator!
If, for some reason, you rely on the reuse of a single variable and the assignment to it, then IMO the easiest approach is to define two macros. One macro which declares the variable (and initializes it, if necessary), and another macro with the code which uses the variable.
It seems regular function works:
void EXPECT_MY_CLASS_EQ(const char* expectedStr, const char* candidateStr)
{
auto ptrCandidate = parseAndGetPtr(candidateStr);
doWork(ptrCandidate);
EXPECT_EQ(expectedStr, convertToString(ptrCandidate));
}
A possible way might be to use __LINE__ or __COUNTER__ with preprocessor symbol concatenation.
In your case, you probably don't need any macro: prefer some static inline function.
Here is a real-life example (using concatenation and __LINE__) from my Bismon's project file cmacros.h line 285 (it is in C, but the same trick could be done in C++)
#define LOCAL_FAILURE_HANDLE_ATBIS_BM(Fil,Lin,Lockset,Flabel,FcodVar,ReasonVar,PlaceVar) \
struct failurehandler_stBM fh_##Lin \
= { \
.pA = {.htyp = typayl_FailureHandler_BM}, \
.failh_magic = FAILUREHANDLEMAGIC_BM, \
.failh_lockset = Lockset, \
.failh_reason = NULL, \
.failh_jmpbuf = {}}; \
curfailurehandle_BM = &fh_##Lin; \
volatile int failcod_##Lin = setjmp(fh_##Lin.failh_jmpbuf); \
FcodVar = failcod_##Lin; \
if (failcod_##Lin) { \
ReasonVar = fh_##Lin.failh_reason; \
PlaceVar = fh_##Lin.failh_place; \
goto Flabel; \
}; \
(void)0
#define LOCAL_FAILURE_HANDLE_AT_BM(Fil,Lin,Lockset,Flabel,FcodVar,ReasonVar,PlaceVar) \
LOCAL_FAILURE_HANDLE_ATBIS_BM(Fil,Lin,Lockset,Flabel,FcodVar,ReasonVar,PlaceVar)
/// code using LOCAL_FAILURE_HANDLE_BM should probably backup and
/// restore the curfailurehandle_BM
#define LOCAL_FAILURE_HANDLE_BM(Lockset,Flabel,FcodVar,ReasonVar,PlaceVar) \
LOCAL_FAILURE_HANDLE_AT_BM(__FILE__,__LINE__,Lockset,Flabel,FcodVar,ReasonVar,PlaceVar)
Back to your question, if you still want a macro: just create a block, e.g.
#define EXPECT_MY_CLASS_EQ(expectedStr, candidateStr) do{ \
auto ptrCandidate = parseAndGetPtr(candidateStr); \
doWork(ptrCandidate); \
EXPECT_EQ(expectedStr, convertToString(ptrCandidate));} while(0)

C++ Macro - pass string and use as a variable name

So i'm working on a small hobby project which i have implemented a very basic reflection of enums. I have come across an issue which i'm struggling to find a solution.
This would be an ideal call which i'm looking for
Reflect_Value("TestStringName", "StringValue")
the first parameter is a string which is intended to be appended onto a variable name and the second to be the actual string value
#define Reflect_Value(name,t) \
namespace Reflection { \
static ReflectedObject object_##name = ReflectedObject(name,t); }\
now the macro would then take that first parameter and be used as object_TestStringName but when i pass the string in the code evaluates to object_"TestStringName" which doesn't compile.
What am i doing wrong here or can anyone provide any solutions to how i could get this functionality please. its important to have the name be something i guess recognisable and also unique so i can reflect many objects
Thanks
I think you can do what you want with the stringification operator #:
#define Reflect_Value(name,t) \
namespace Reflection { \
static ReflectedObject object_##name = ReflectedObject( #name, #t ); }\
You'd then call the macro with unquoted arguments:
Reflect_Value(TestStringName, StringValue)
Don't pass a string, but stringize it:
#define stringize(name) #name
#define Reflect_Value(name,t) \
namespace Reflection { \
static ReflectedObject object_##name = ReflectedObject(stringize (name),t); }
Then:
Reflect_Value(TestStringName, "StringValue")

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.

Throwing function-like variadic macro wrapping, replacing thrown exception

Suppose I have a third party library that provides a function-like ThirdPartyMacro macro that is:
Variadic and accepts arbitrary tokens, not just well formed c++ expressions. After parsing the arguments ThirdPartyMacro extracts some tokens that it assumes to be identifiers denoting variables in the scope of it's invocation, and uses them as such.
Evaluates to some value of a known type.
May throw an exception of type ThirdPartyException
I want to wrap this up by writing a macro MyMacro that will behave exactly like ThirdPartyMacro but throw MyException whenever ThirdPartyMacro would throw ThirdPartyException.
Is it possible? If so, how?
Not that due to (1) MyMacro cannot be a function, as it's arguments are not something that can be passed as function parameters.
A lambda will help:
#define MyMacro(...) \
[&]{ try { return ThirdPartyMacro(__VA_ARGS__); } \
catch( const ThirdPartyException& e ) \
{ throw MyException( e.what() ); } }()

Rare cases where MACROs must be used

Debugging macros can take a lot of time. We are much better off
avoiding them except in the very rare cases when neither constants,
functions nor templates can do what we want.
What are the rare cases?
If you want actual textual replacement, that's where you use macros. Take a look at Boost.Preprocessor, it's a great way to simulate variadic templates in C++03 without repeating yourself too much.
In other words, if you want to manipulate the program code itself, use macros.
Another useful application is assert, which is defined to be a no-op when NDEBUG is not defined (usually release mode compilation).
That brings us to the next point, which is a specialization of the first one: Different code with different compilation modes, or between different compilers. If you want cross-compiler support, you can't get away without macros. Take a look at Boost in general, it needs macros all the time because of various deficiencies in various compilers it has to support.
Another important point is when you need call-site information without wanting to bug the user of your code. You have no way to automatically get that with just a function.
#define NEEDS_INFO() \
has_info(__FILE__, __LINE__, __func__)
With a suitable declaration of has_info (and C++11/C99 __func__ or similar).
This question doesn't appear to have a definite, closed-form answer, so I'll just give a couple of examples.
Suppose you want to print information about a given type. Type names don't exist in the compiled code, so they cannot possibly be expressed by the language itself (except for C++ extensions). Here the preprocessor must step in:
#define PRINT_TYPE_INFO(type) do { printf("sizeof(" #type ") = %zu\n", sizeof(type)); } while (false)
PRINT_TYPE_INFO(int);
PRINT_TYPE_INFO(double);
Similarly, function names are not themselves variable, so if you need to generate lots of similar names, the preprocessor helps:
#define DECLARE_SYM(name) fhandle libfoo_##name = dlsym("foo_" #name, lib);
DECLARE_SYM(init); // looks up "foo_init()", declares "libfoo_init" pointer
DECLARE_SYM(free);
DECLARE_SYM(get);
DECLARE_SYM(set);
My favourite use is for dispatching CUDA function calls and checking their return value:
#define CUDACALL(F, ARGS...) do { e = F(ARGS); if (e != cudaSuccess) throw cudaException(#F, e); } while (false)
CUDACALL(cudaMemcpy, data, dp, s, cudaMemcpyDeviceToHost);
CUDACALL(cudaFree, dp);
Since this an Open ended Question an trick which I often use and find convenient.
If you want to write an wrapper function over an free function like say malloc, without modifying each and every instance in your code where the function is called then a simple macro shall suffice:
#define malloc(X) my_malloc( X, __FILE__, __LINE__, __FUNCTION__)
void* my_malloc(size_t size, const char *file, int line, const char *func)
{
void *p = malloc(size);
printf ("Allocated = %s, %i, %s, %p[%li]\n", file, line, func, p, size);
/*Link List functionality goes in here*/
return p;
}
You can often use this trick to write your own memory leak detector etc, for debugging purposes.
Though the example is for malloc it can be re-used for any free standing function really.
One example is token pasting if you want to use a value as both an identifier and a value. From the msdn link:
#define paster( n ) printf_s( "token" #n " = %d", token##n )
int token9 = 9;
paster( 9 ); // => printf_s( "token9 = %d", token9 );
There are also cases in the c++ faq where though there may be alternatives the macro solution is the best way to do things. One example is pointers to member functions where the right macro
#define CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember))
makes it much easier to make the call rather than deal with all the assorted hair of trying to do it w/out the macro.
int ans = CALL_MEMBER_FN(fred,p)('x', 3.14);
Honestly I just take their word for it and do it this way, but apparently it gets worse as the calls become more complicated.
Here's an example of someone trying to go it alone
When you need the call itself to optionally return from a function.
#define MYMACRO(x) if(x) { return; }
void fn()
{
MYMACRO(a);
MYMACRO(b);
MYMACRO(c);
}
This is usually used for small bits of repetitive code.
I am not sure that debugging macros take a lot of time. I would believe that I find simple the debugging of macros (even 100 lines monster macros), because you have the possibility to look at the expansion (using gcc -C -E for instance) - which is less possible with e.g. C++ templates.
C macros are useful when in several occasions:
you want to process a list of things in several different ways
you want to define an "lvalue" expression
you need efficiency
you need to have the location of the macro thru __LINE__)
you need unique identifiers
etc etc
Look at the many uses of #define-d macros inside major free softwaare (like Gtk, Gcc, Qt, ...)
What I regret a lot is that C macro language is so limited.... Imagine if the C macro language would have been as powerful as Guile!!! (Then you could write things as complex as flex or bison as macros).
Look at the power of Common Lisp macros!
If you are using C, you need to use macros to simulate templates.
From http://www.flipcode.com/archives/Faking_Templates_In_C.shtml
#define CREATE_VECTOR_TYPE_H(type) \
typedef struct _##type##_Vector{ \
type *pArray; \
type illegal; \
int size; \
int len; \
} type##_Vector; \
void type##_InitVector(type##_Vector *pV, type illegal); \
void type##_InitVectorEx(type##_Vector *pV, int size, type illegal); \
void type##_ClearVector(type##_Vector *pV); \
void type##_DeleteAll(type##_Vector *pV); \
void type##_EraseVector(type##_Vector *pV); \
int type##_AddElem(type##_Vector *pV, type Data); \
type type##_SetElemAt(type##_Vector *pV, int pos, type data); \
type type##_GetElemAt(type##_Vector *pV, int pos);
#define CREATE_VECTOR_TYPE_C(type) \
void type##_InitVector(type##_Vector *pV, type illegal) \
{ \
type##_InitVectorEx(pV, DEF_SIZE, illegal); \
} \
void type##_InitVectorEx(type##_Vector *pV, int size, type illegal) \
{ \
pV-len = 0; \
pV-illegal = illegal; \
pV-pArray = malloc(sizeof(type) * size); \
pV-size = size; \
} \
void type##_ClearVector(type##_Vector *pV) \
{ \
memset(pV-pArray, 0, sizeof(type) * pV-size); \
pV-len = 0; \
} \
void type##_EraseVector(type##_Vector *pV) \
{ \
if(pV-pArray != NULL) \
free(pV-pArray); \
pV-len = 0; \
pV-size = 0; \
pV-pArray = NULL; \
} \
int type##_AddElem(type##_Vector *pV, type Data) \
{ \
type *pTmp; \
if(pV-len = pV-size) \
{ \
pTmp = malloc(sizeof(type) * pV-size * 2); \
if(pTmp == NULL) \
return -1; \
memcpy(pTmp, pV-pArray, sizeof(type) * pV-size); \
free(pV-pArray); \
pV-pArray = pTmp; \
pV-size *= 2; \
} \
pV-pArray[pV-len] = Data; \
return pV-len++; \
} \
type type##_SetElemAt(type##_Vector *pV, int pos, type data) \
{ \
type old = pV-illegal; \
if(pos = 0 && pos <= pV-len) \
{ \
old = pV-pArray[pos]; \
pV-pArray[pos] = data; \
} \
return old; \
} \
type type##_GetElemAt(type##_Vector *pV, int pos) \
{ \
if(pos = 0 && pos <= pV-len) \
return pV-pArray[pos]; \
return pV-illegal; \
}
Consider the standard assert macro.
It uses conditional compilation to ensure that the code is included only in debug builds (rather than relying on the optimizer to elide it).
It uses the __FILE__ and __LINE__ macros to create references to the location in the source code.
I've once used macro to generate a large string array along with index enumeration:
strings.inc
GEN_ARRAY(a)
GEN_ARRAY(aa)
GEN_ARRAY(abc)
GEN_ARRAY(abcd)
// ...
strings.h
// the actual strings
#define GEN_ARRAY(x) #x ,
const char *strings[]={
#include "strings.inc"
""
};
#undef GEN_ARRAY
// indexes
#define GEN_ARRAY(x) enm_##x ,
enum ENM_string_Index{
#include "strings.inc"
enm_TOTAL
};
#undef GEN_ARRAY
It is useful when you have several array that has to be kept synchronized.
To expand on #tenfour's answer about conditional returns: I do this a lot when writing Win32/COM code where it seems I'm checking an HRESULT every second line. For example, compare the annoying way:
// Annoying way:
HRESULT foo() {
HRESULT hr = SomeCOMCall();
if (SUCCEEDED(hr)) {
hr = SomeOtherCOMCall();
}
if (SUCCEEDED(hr)) {
hr = SomeOtherCOMCall2();
}
// ... ad nauseam.
return hr;
}
With the macro-y nice way:
// Nice way:
HRESULT foo() {
SUCCEED_OR_RETURN(SomeCOMCall());
SUCCEED_OR_RETURN(SomeOtherCOMCall());
SUCCEED_OR_RETURN(SomeOtherCOMCall2());
// ... ad nauseam.
// If control makes it here, nothing failed.
return S_OK;
}
It's doubly handy if you wire up the macro to log any failures automatically: using other macro ideas like token pasting and FILE, LINE, etc; I can even make the log entry contain the code location and the expression that failed. You could also throw an assert in there if you wanted to!
#define SUCCEED_OR_RETURN(expression) { \
HRESULT hrTest = (expression); \
if (!SUCCEEDED(hrTest)) { \
logFailure( \
#expression, \
HResultValueToString(hrTest), \
__FILE__, \
__LINE__, \
__FUNCTION__); \
return hrTest; \
} \
}
Debugging would be much easier as your project will be in divided into various modules for each task. Macros can be very useful when you have a large and complex software project. But there are some pitfalls which are stated here.
For me it's more comfortable to use macros for constants and for parts of code that have no separated logical functionality. But there are some important differences between (inline) functions and (function-like) macros, here they are:
http://msdn.microsoft.com/en-us/library/bf6bf4cf.aspx