How can I get full, expanded, stringified macros from boost::wave? - c++

I have a file containing the following:
#define str(s) s
#define xstr(s) #s
#define foo 4
#define first str(foo)
#define second xstr(foo)
When I pass this into boost::wave, the macromap contains the following:
first=str(foo)
foo=4
second=xstr(foo)
str(s)=#s
xstr(s)=str(s)
How can I get the macros to be fully expanded such that:
first="foo"
second=4
I thought that boost::wave supported macro re-scanning and lookup. Is there something I'm missing, or do I need to do something with the processing hooks to make the expansion happen? I mean, I can write code to descend the tree, but it would be certainly nice if I didn't have to do that work if I was missing something important.

The clue from n.m. was important. Macros may be defined and undefined whenever, so it's only the instance of use which is relevant.
This was far easier than I had expected. If I have something that looks like this in a header file:
#define str(s) #s
#define xstr(s) str(s)
...
#define MAJORVER 1
#define MINORVER 0
#define MAJORBUILD 0
#define MINORBUILD 1
#define FULLBUILDSTRING xstr(MAJORVER) "." \
xstr(MINORVER) "." \
xstr(MAJORBUILD) "." \
xstr(MINORBUILD)
The FULLBUILDSTRING macro will evaluate to just the string as declared. However, if I have some code that makes use of the macro directly, such as in
static char const full_build_string[] = FULLBUILDSTRING;
It will evaluate to the following when Wave processes it:
static char const full_build_string = "1" "." "0" "." "0" "." "1";
If you need to see how the macros are defined after processing is complete, you can always do something like so (this is taken from the Wave driver code):
auto end = ctx.macro_names_end();
for (auto it = ctx.macro_names_begin(); it != end; ++it) {
typedef std::vector<context_type::token_type> parameters_type;
bool has_pars = false;
bool predef = false;
context_type::position_type pos;
parameters_type pars;
context_type::token_sequence_type def;
if (ctx.get_macro_definition(*it, has_pars, predef, pos, pars, def)) {
// if has_pars is true, you can iterate through pars to see
// parameters for function macros
// iterate through def to see the macro definition
}
}
Of course, the macros are stored in non-expanded form.
(n.m., if you write an answer, I will accept it)

Related

C++ Stop Preprocessor Macro Expansion

Here is my example code https://godbolt.org/z/VKgKik
#define delete MyCustomDelete(__FILE__, __LINE__), delete
#define CAT(X,Y) CAT2(X,Y)
#define CAT2(X,Y) X##Y
#define CAT_3(X,Y,Z) CAT(X,CAT(Y,Z))
class A {
A() = CAT_3(de,le,te);
};
The godbolt example is setup to display the preprocessor output. The goal is that at the end of the preprocessor pass i want the output code to be
class A {
A() = delete;
};
currently "ThisShouldNotshowUp" is displayed there instead. I thought the use of the ## operator would stop the preprocessor from reexpanding but it did not.
I realize removing the "#define delete" would solve the problem but I need this define there. The reason I have created a macro with the same name as delete is because I want to be able to track the news and deletes, and If a memory leak occurs I can see what line of code aloced it. This macro thus means I can continue to use the keyword delete in my code and the File and line numbers get filled in for free. As far as i know there is no other way to achieve this functionailty except by defined a delete macro. This is the crux of the problem. The delete macro has given me a powerful debug tool however it has removed a useful language feature for me to use.
You have no chance in creating a preprocessing token that is the name of an object-like macro from expanding a macro. The relevant section of n3337 is [cpp.rescan]. I quote a shortened part of the first paragraph in it.
After all parameters in the replacement list have been substituted and # and ## processing has taken place [...]. Then the resulting preprocessing token sequence is rescanned [...] for more macro names to replace.
Nonwithstanding the problem, that delete is technically forbidden to be a macro name, there is no way to prevent the macro name to be recognized while rescanning.
You probably mixed up the fact that ## operator does use it's parameters without expansion with the idea that the result of ## doesn't undergo macro expansion.
What you're trying to do is not possible, as Michael Karcher's answer states: #define delete already makes the program ill-formed, and expanding an object-like macro (outside its own expansion) cannot be avoided.
However, for your particular use case detailed in the question, a workaround is possible. You could put your #define delete into a header file (let's call it debug_delete.hxx), like this:
#ifdef delete
# undef delete
#endif
#define delete MyCustomDelete(__FILE__, __LINE__), delete
Then, create another header file (let's call it normal_delete.hxx):
#ifdef delete
# undef delete
#endif
Note in particular that there is no mechanism in these headers to prevent multiple inclusion; in fact, we want them includable an arbitrary number of times.
Then, wrap code which must use = delete; in appropriate #include directives:
class A {
#include "normal_delete.hxx"
A() = delete;
#include "debug_delete.hxx"
~A() { delete p; }
};
(Yes, it's ugly, but what you're doing is sort of ugly in the first place, so ugly code may be required to make it work).
Presumably you want to use a macro so you can turn on and off your delete tracking. If you're only using this on your source, and not trying to rig it up to transform existing C++, you could use a function-like macro in order to effect the optional tracking that you desire.
#define TRACK_DELETES 0
#if TRACK_DELETES
#define DELETE( a ) \
do { MyCustomDelete( __FILE__, __LINE__ ); delete (a); } while (0)
#define DELETEALL( a ) \
do { MyCustomDelete( __FILE__, __LINE__ ); delete [] (a); } while (0)
#else
#define DELETE( a ) do { delete (a) ; } while(0)
#define DELETEALL( a ) do { delete [] (a) ; } while(0)
#endif
int main(){
DELETE( A );
DELETEALL( B );
return 0;
}
See if this does what you want with TRACK_DELETES set to 0 or 1 under gcc -E.
You'll want to leave the bare delete keyword alone so it can be used appropriately.

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.

Do pre-processor macros for debug log statements have a place in C++?

Recently I have been reading Effective C++ Second Edition by Scott Meyers to improve on C++ best practices. One of his listed items encourages C++ programmers to avoid pre-processor macros and 'prefer the compiler'. He went as far as saying there are almost no reasons for macro in C++ aside from #include and #ifdef/#ifndef.
I agree with his reasoning, as you can accomplish the following macro
#define min(a,b) ((a) < (b) ? (a) : (b))
with the following C++ language features
template<class T>
inline const T & min(const T & a, const T & b) {
return a < b ? a : b;
}
where inline gives the compiler the option to remove the function call and insert inline code and template which can handle multiple data types who have an overloaded or built in > operator.
EDIT-- This template declaration will not completely match the stated macro if the data type of a and b differ. See Pete's comment for an example.
However, I am curious to know if using macros for debug logging is a valid use in C++. If the method I present below is not good practice, would someone be kind to suggest an alternative way?
I have been coding in Objective-C for the last year and one of my favorite 2D engines (cocos2d) utilized a macro to create logging statements. The macro is as follows:
/*
* if COCOS2D_DEBUG is not defined, or if it is 0 then
* all CCLOGXXX macros will be disabled
*
* if COCOS2D_DEBUG==1 then:
* CCLOG() will be enabled
* CCLOGERROR() will be enabled
* CCLOGINFO() will be disabled
*
* if COCOS2D_DEBUG==2 or higher then:
* CCLOG() will be enabled
* CCLOGERROR() will be enabled
* CCLOGINFO() will be enabled
*/
#define __CCLOGWITHFUNCTION(s, ...) \
NSLog(#"%s : %#",__FUNCTION__,[NSString stringWithFormat:(s), ##__VA_ARGS__])
#define __CCLOG(s, ...) \
NSLog(#"%#",[NSString stringWithFormat:(s), ##__VA_ARGS__])
#if !defined(COCOS2D_DEBUG) || COCOS2D_DEBUG == 0
#define CCLOG(...) do {} while (0)
#define CCLOGWARN(...) do {} while (0)
#define CCLOGINFO(...) do {} while (0)
#elif COCOS2D_DEBUG == 1
#define CCLOG(...) __CCLOG(__VA_ARGS__)
#define CCLOGWARN(...) __CCLOGWITHFUNCTION(__VA_ARGS__)
#define CCLOGINFO(...) do {} while (0)
#elif COCOS2D_DEBUG > 1
#define CCLOG(...) __CCLOG(__VA_ARGS__)
#define CCLOGWARN(...) __CCLOGWITHFUNCTION(__VA_ARGS__)
#define CCLOGINFO(...) __CCLOG(__VA_ARGS__)
#endif // COCOS2D_DEBUG
This macro provides for incredible utility which I will want to incorporate in my C++ programs. Writing a useful log statement is as simple as
CCLOG(#"Error in x due to y");
What is even better, is that if the COCOS2D_DEBUG is set to 0, then these statements never see the light of day. There is no overhead for checking a conditional statement to see if logging statements should be used. This is convenient when making the transition from development to production. How could one recreate this same effect in C++?
So does this type of macro belong in a C++ program? Is there a better, more C++ way of doing this?
First, Scott's statement was made at a time when macros were
considerably overused, for historical reasons. While it is
generally true, there are a few cases where macros make sense.
Of of these is logging, because only a macro can automatically
insert __FILE__ and __LINE__. Also, only a macro can
resolve to absolutely nothing (although based on my experience,
this isn't a big deal).
Macros such as you show aren't very frequent in C++. There are
two usual variants for logging:
#define LOG( message ) ... << message ...
which allows messages in the form " x = " << x, and can be
completely suppressed by redefining the macro, and
#define LOG() logFile( __FILE__, __LINE__ )
where logFile returns a wrapper for an std::ostream, which
defines operator<<, and permits such things as:
LOG() << "x = " << x;
Done this way, all of the expressions to the right of LOG()
will always be evaluated, but done correctly, no formatting will
be done unless the log is active.
There are "right" things to use macros for and there are bad uses of macros. Using macros where functions work is a bad idea. Using macros where functions DON'T do the same thing is perfectly good in my book.
I quite often use constructs like this:
#defien my_assert(x) do { if (!x) assert_failed(x, #x, __FILE__, __LINE__); } while(0)
template<typename T>
void assert_failed(T x, const char *x_str, const char *file, int line)
{
std::cerr << "Assertion failed: " << x_str << "(" << x << ") at " << file << ":" << line << std::endl;
std::terminate();
}
Another trick using the stringizing "operator" is something like this:
enum E
{
a,
b,
c,
d
};
struct enum_string
{
E v;
const char *str;
};
#define TO_STR(x) { x, #x }
enum_string enum_to_str[] =
{
TO_STR(a),
TO_STR(b),
TO_STR(c),
TO_STR(d),
};
Saves quite a bit of repeating stuff...
So, yes, it's useful in some cases.

Generic method to display enum value names

Is there a way to display the name of an enum's value?
say we have:
enum fuits{
APPLE,
MANGO,
ORANGE,
};
main(){
enum fruits xFruit = MANGO;
...
printf("%s",_PRINT_ENUM_STRING(xFruit));
...
}
using the preprocessor
#define _PRINT_ENUM_STRING(x) #x
won't work as we need to get the value of the variable 'x' and then convert It to string.
Is this at all possible in c/C++?
You could use the preprocessor to do this, I believe this technique is called X-Macros:
/* fruits.def */
X(APPLE)
X(MANGO)
X(ORANGE)
/* file.c */
enum fruits {
#define X(a) a,
#include "fruits.def"
#undef X
};
const char *fruit_name[] = {
#define X(a) #a,
#include "fruits.def"
#undef X
};
Note that the last entry includes a trailing comma, which is allowed in C99 (but not in C89). If that is a problem you can add sentinal values. It is also possible to make the macro more complicated by giving multiple arguments for custom names or enum values, etc:
X(APPLE, Apple, 2)
#define X(a,b,c) a = c, /* in enum */
#define X(a,b,c) [c] = #b, /* in name array */
Limitations: You cannot have negative constants and your array is sizeof (char *) * largest_constant. But you could work around both by using an extra lookup table:
int map[] = {
#define X(a,b,c) c,
#include "fruits.def"
#undef X
};
This doesn't work of course. What does work is generating an extra set of enum constants as keys for the names:
enum fruits {
#define X(a,b,c) a ## _KEY,
#include "fruits.def"
#undef X
#define X(a,b,c) a = c,
#include "fruits.def"
#undef X
};
Now you can find the name of X(PINEAPPLE, Pineapple, -40) by using fruit_name[PINEAPPLE_KEY].
People noted that they didn't like the extra include file. You don't need this extra file, you also use a #define. This may be more appropriate for small lists:
#define FRUIT_LIST X(APPLE) X(ORANGE)
And replace #include "fruits.def with FRUIT_LIST in the previous examples.
You can use a mapping in this case.
char *a[10] = { "APPLE","MANGO","ORANGE"};
printf("%s",a[xFruit]);
Yes the preprocessor won't work unless you provide the exact enum -value.
Also check this question for more insights.
I've used preprocessor programming successfully to get a macro of this kind:
DEFINE_ENUM(Fruits, (Apple)(Mango)(Orange));
It does a tad more than just printing the names, but it could easily be simplified to 2 switches if necessary.
It's based on Boost.Preprocessor facilities (notably BOOST_PP_SEQ_FOREACH) which is a must have for preprocessor programming, and I find it much more elegant than the X facility and its file reinclusion system.
public enum LDGoalProgressUpdateState
{
[Description("Yet To Start")]
YetToStart = 1,
[Description("In Progress")]
InProgress = 2,
[Description("Completed")]
Completed = 3
}
var values = (ENUMList[])Enum.GetValues(typeof(ENUMList));
var query = from name in values
select new EnumData//EnumData is a Modal or Entity
{
ID = (short)name,
Name = GetEnumDescription(name)//Description of Particular Enum Name
};
return query.ToList();
region HelperMethods
public static string GetEnumDescription(Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes != null && attributes.Length > 0)
return attributes[0].Description;
else
return value.ToString();
}
#endregion

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