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

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")

Related

Understanding macro code statement with lambda and __attribute__

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

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 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())
}

Is it possible to use a macro to create typedefs?

How can I create a typedef using a macro (#define)?
I am, for various reasons, trying to use a macro to do typedef'ing in C. Something along the lines of templates for C++.
As an example, I would expect the preprocessor to expand the #define and typedef a struct whose "content" member is of type char:
#define DEFINE_FOO_TYPE(content_type__, content_type_name__) \
typedef struct { \
content_type__ content; \
} content_type_name__
DEFINE_FOO_TYPE(char, foo_t);
foo_t foo_var;
foo_var.content = 'g';
Apparently that is not the case. Is it possible to do these sort of things in C at all, or is the only way a C++ template?
To preempt questions along the lines of "why don't you just use a C++ template?". The answer is that I'm trying to do it in C because it's fun.
Try this:
#define DEFINE_FOO_TYPE(content_type__, content_type_name__) \
typedef struct { \
content_type__ content; \
} content_type_name__
DEFINE_FOO_TYPE(char, foo_t);
int main() {
foo_t foo_var;
foo_var.content = 'g';
return 0;
}
I.e. use content_type_name__ instead of element_type_name__
Proof of compilation
I posted in a comment because I thought it was too trivial, but here it is:
Surely you are not just pasting that quoted code into gcc, are you? You can't just execute code outside any function. Put the last line inside a function.
simply put the last two lines of code into main()
or any function it will work for sure.

Enum declaration inside a scope that is a parameter of a macro

I am trying to create a macro that takes a scope as a parameter.
I know, it is probably not a good thing etc etc.
I was trying this and got the problem that preprocessor looks for commas and parentheses... the problem is with enum.
How would I declare a enum inside a scope that is a parameter of a macro?
when the compiler see the comma between enum itens, it takes it as a separator.
If you are curious to know why I entered into this, is because I need to register my namespaces and classes, for namespaces I need to know when they are closed, so I was thinking to create a macro that initially calls a static function that register the namespace, encapsulate its contents and finally call a static function that removes the namespace from the registry.
With a macro it would be easier for the coder to do this and make sure he doesn't forget to remove the namespace in the end of the bracket.
Thanks,
Joe
EDIT:
I want a macro that accepts a scope as parameters:
#define MYMACRO(unkownscope) unknownscope
class MYMACRO({
// please, don't take this code seriously, it is just an example so you can understand my question
});
now, if I try:
#define MYMACRO(unkownscope) unknownscope
class MYMACRO({
enum {
anything = 1,
everything = 2
};
});
it won't compile because of the comma inside the enum, because the compiler thinks it is a separator of the macro. It doesn't happen with commas inside parentheses, example:
int a(){
int x = anyfunction(1, 2);
}
would compile normally because the comma is inside a double parentheses.
Sorry for not being able to explain earlier... my english is not that good and the words just keep skipping me =[
Ty for the answers!
Joe
It sounds like you are pushing the preprocessor beyond where it's willing to go. While it's not as elegant, how about breaking your macro in two (one pre- and one post-) and rather then passing a "scope" as parameter, you surround your scope with you pre- and post- macros.
So, if your macro looks something like:
SOMACRO({ ... });
You would instead do something like:
PRESOMACRO();
{ ... };
POSTSOMACRO();
#define SCOPED_STUFF(pre,post) pre; STUFF; post;
#define STUFF enum {a,b,c}
SCOPED_STUFF(a,b)
#undef STUFF
#define STUFF enum {q,r}
SCOPED_STUFF(c,d)
#undef STUFF
You are attempting to replicate RAII with a macro.
#define SCOPE(ns) NamespaceRegistrar _ns_rar(ns);
struct NamespaceRegistrar {
std::string _ns;
NamespaceRegistrar(const std::string& ns) : _ns(ns) { AcquireResource(_ns); }
~NamespaceRegistrar() { ReleaseResource(_ns); }
};
{
SCOPE("Foo")
// stuff
}
I have no idea what you are talking about with regard to enums.
You already noticed what the problem is, an article on boostpro.com sums the problem up.
There are work-arounds, but i'd go for utilizing Boost.Preprocessor.
Without knowing exactly what you're trying to achieve syntactically, something like this might be what you are looking for (edited to PP_SEQ):
#define MAKE_ENUM(Name, Seq) enum Name { BOOST_PP_SEQ_ENUM(Seq) }
MAKE_ENUM(foo, (a)(b)(c));