How to make a Macro parser in C++ project - c++

in the project, there are a lot of macros
such as
#define a (b+c)
#define b (e+d)
sometimes you need to decide the actual value of a .
so i am wondering if there are any tools for doing that, calculating all the macros and give the actual value as comment: (like below)
#define a (b+c) //a = 5
Are there any opensource project related on this macro parsing job?
thanx

I don't know how such a tool could exist as a macro may have an argument that is only known during execution(for instance #define sum(a,b) (a+b)). As for the value during runtime - any reasonable debugger will handle that.

Related

Using MACROs to get the 'name' of function parameters

I've implemented a log function, that eventually is being used identically all over the code.
void func(int foo, int bar){
log_api_call("foo", foo, "bar",bar)
...
}
so I've decided to make it easier and just extract the variable names.
so it would be something like
log_api_call(foo,bar)
or even better
log_api_call()
and it would expand to log_api_call("foo", foo, "bar",bar) somehow.
I have no idea even where to start to 'extract' the function variable names.
help would be much appreciated.
Edit:
I understand that what I've asked previously is outside of the C++ preprocessor capabilities, but can C MACROS expand log_api(a,b) to log_api_call("a", a, "b", b) for any number of parameters?
for defined number the job is trivial.
Thanks.
This isn't actually too difficult.
I'd recommend a slight change in spec though; instead of:
expand log_api(a,b) to log_api_call("a", a, "b", b)
...it's more useful to expand something like NAMED_VALUES(a,b) to "a",a,"b",b. You can then call log_api(NAMED_VALUES(a,b)), but your log_api can stay more generic (e.g., log_api(NAMED_VALUES(a,b),"entering function") is possible). This approach also avoids a lot of complications about zero-argument cases.
// A preprocessor argument counter
#define COUNT(...) COUNT_I(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1,)
#define COUNT_I(_9,_8,_7,_6,_5,_4,_3,_2,_1,X,...) X
// Preprocessor paster
#define GLUE(A,B) GLUE_I(A,B)
#define GLUE_I(A,B) A##B
// chained caller
#define NAMED_VALUES(...) GLUE(NAMED_VALUES_,COUNT(__VA_ARGS__))(__VA_ARGS__)
// chain
#define NAMED_VALUES_1(a) #a,a
#define NAMED_VALUES_2(a,...) #a,a,NAMED_VALUES_1(__VA_ARGS__)
#define NAMED_VALUES_3(a,...) #a,a,NAMED_VALUES_2(__VA_ARGS__)
#define NAMED_VALUES_4(a,...) #a,a,NAMED_VALUES_3(__VA_ARGS__)
#define NAMED_VALUES_5(a,...) #a,a,NAMED_VALUES_4(__VA_ARGS__)
#define NAMED_VALUES_6(a,...) #a,a,NAMED_VALUES_5(__VA_ARGS__)
#define NAMED_VALUES_7(a,...) #a,a,NAMED_VALUES_6(__VA_ARGS__)
#define NAMED_VALUES_8(a,...) #a,a,NAMED_VALUES_7(__VA_ARGS__)
#define NAMED_VALUES_9(a,...) #a,a,NAMED_VALUES_8(__VA_ARGS__)
This supports up to 9 arguments, but it should be easy to see how to expand to more.
This is not possible in standard C++11 (or standard C11 - which nearly shares its preprocessor with C++). The C or C++ preprocessor don't know the AST of your code passed to the compiler (because it is running before the actual parsing of your code).
I have no idea even where to start to 'extract' the function variable names.
Notice that variable and function names are known only at compilation time (after preprocessing). So if you want them, you need to work during compilation. At execution time variables and functions names are generally lost (and you could strip your executable).
You could generate your C++ code (e.g.using some other preprocessor like GPP or M4, or writing your own thing).
You could customize your C++ compiler (e.g. with an extension in GCC MELT, or a GCC plugin) to e.g. have log_api_call invoke some new magic builtin (whose processing inside the compiler would do most of the job). This would take months and is very compiler specific, I don't think it is worth the pain.
You could parse DWARF debugging info (that would also take months, so I don't think it would be wise).
(I am implicitly thinking of C++ code compiled on a Linux system)
Read more about aspect programming.
If you want such powerful meta-programming facilities, C++ is the wrong programming language. Read more about the powerful macro system of Common Lisp...
but can C MACROS expand log_api(a,b) to log_api_call("a", a, "b", b) for any number of parameters? for defined number the job is trivial.
No. You need a more powerful preprocessor to do that job (or write your own). For that specific need, you might consider customizing your source code editor (e.g. write a hundred lines of ELisp code doing that extraction & expansion job at edit time for emacs).
PS In practice you could find some library (probably boost) limiting the arguments to some reasonable limit
I think the best you can achieve from inside the language is writing a macro LOG_API_CALL(foo,bar) that expands to log_api_call("foo", foo, "bar", bar):
#define LOG_API_CALL(P1,P2) log_api_call(#P1,P1,#P2,P1)
This gets pretty tricky if you want to support arbitrarily many arguments with a single macro name, but you could also have a separate macro for each number of arguments.
and it would expand to log_api_call("foo", foo, "bar",bar) somehow.
This is not possible in Standard C++.

Exclude parts from compilation - still syntax-check

We have a pretty large project here in C++/.NET/Visual Studio, for performance testing we incuded some code that makes it possible to evaluate the execution time between certain points.
PERFORMANCE_TEST BeginMeasureTime("execute someCode")
someCode
PERFORMANCE_TEST EndMeasureTime("execute someCode")
Usually while developing the PERFORMANCE_TEST macro would be set to // so the evaluation code is switched off. So if code / interfaces etc. change and the code after the PERFORMANCE_TEST macro becomes invalid, the developer will not notice that.
Is there any smarter way to have the performance evaluation code only built in a special version of the project but still make sure that it stays consistent? How would you normally do something like that?
One easy way would be to change
PERFORMANCE_TEST xxx
to
PERFORMANCE_TEST(xxx)
Then instead of
#if PERFORMANCE_TEST_ENABLED
#define PERFORMANCE_TEST
#else
#define PERFORMANCE_TEST //
#endif
you could have
#if PERFORMANCE_TEST_ENABLED
#define PERFORMANCE_TEST(x) {x;}
#else
#define PERFORMANCE_TEST(x) if(0) { x; }
#endif
An optimizing compiler should generate no code for the second version if performance tests are disabled (or at the very least it'll not branch on the if), but it'll still be part of the compilation.
Alternatively, if build times aren't a huge concern you could simply always build both versions into separate directories.
It's been a while since I did something like this the following should be what you want. If the MACRO is defined then the function is included, else it the function is a noop and compiled out the code.
#ifdef MACRO
#define MACRO_NAME(arg1, arg2, ...) [code to expand to]
#else
#define MACRO_NAME(arg1, arg2, ...) noop
#endif
Update:
Ok so I slightly got the question a bit incorrect.
Most static analysis tools can be configured to scan certain #defines
CPPCheck for example can be given the following arguments.
-D<ID> Define preprocessor symbol. Unless --max-configs or
--force is used, Cppcheck will only check the given
configuration when -D is used.
Example: '-DDEBUG=1 -D__cplusplus'.
So you can then scan the code twice, thus achieving your goal.
I would say this is the best of both before you can add more scans if you add more #define
Or you can use some of the following to scan more configurations.
-f, --force Force checking of all configurations in files. If used
together with '--max-configs=', the last option is the
one that is effective.
and
--max-configs=<limit>
Maximum number of configurations to check in a file
before skipping it. Default is '12'. If used together
with '--force', the last option is the one that is
effective.
We used this type of operation at a previous company, we build code for WIN32, Pocket PC and WM5 and WM6 all from the same code base but had static checking on all build configurations. But the end result was the removal of non redundant code in all builds.

Arduino - How to write Macro that define used pins by name and number and throw compiler error if pin is used elsewhere

I have been playing with this for the last 2 hours now. It should be simple but it does not work. I am not really familiar with macros and I never used them really because of their known instability. But in this case... I don't see any other better way to not use any chip memory.
What I want is not to use memory on chip for this so I choose precompiler directives, especially macros. The macro just have to define stuff, not return anything. I want that macro to be equivalent to this code :
#define PIN3 = 13;
#define PINLED = 13;
And it should be called like that :
P(13,LED);
So that way I can reference PINLED in my code and get a compiler error if any other library or code I use happens to use PIN13 when I put the P(13,LED) in the top of all the files that uses this pin in my project. I want something that names all pins the same way.
I want the 2 constants/defines to be "defined" so PIN13 cause a compiler error, but PINLED might be named different in many projects
I have tried this :
#define P(no_,name_) \
if (true) { \
PIN##name_ = no_; \
PIN##no_ = no_; \
}\
else true
This works but does only 1 define instead of 2 :
#define P(no_,name_) PIN##name_ = no_
This was suggested by many as the correct syntax. I also tried with the do... while(0) syntax and other tricks so I can use the macro as a function with a ; after it but is does not work and always throws some error.
I am using the Ino project to build because I cannot live with the arduino IDE which is pure crap compared to other IDEs.
Sorry, but your question is hardly understandable. You say you want to check whether a pin has already been used in another part of the project, and in the same time you're showing code for defining macros in macros.
But that's where it hurts, like #graben showed, it's simply not possible to achieve in C. First of all both of your syntaxes are wrong:
#define P(no_,name_) PIN##name_ = no_
you're not creating a macro name PINLED to which you assign 13, but you're assigning to the C variable PINLED the value 13. To make your PIN definition macro work, you'll need to use const int variables, which usually are easily optimized by the compiler.
Now, to get to the goal you say you want to achieve, I think it's very unlikely you can do it in macro processor code, at least in an elegant way...
And I don't think that's even necessary!
If you design well your libraries, you should not be using the pin number throughout your code and libraries, but design them so you define pins for each library at the library initialization stage. That's why usually Arduino libraries work in three steps:
allocate the memory (which is done by calling the constructor, which is often made in the included header file as a global object) ;
configure the instance (which is done with the .begin() method)
use the instance
so basically, if you have all your pins defined in the same file, you should not run into pin reuse elsewhere in your code.

Why use #define instead of a variable

What is the point of #define in C++? I've only seen examples where it's used in place of a "magic number" but I don't see the point in just giving that value to a variable instead.
The #define is part of the preprocessor language for C and C++. When they're used in code, the compiler just replaces the #define statement with what ever you want. For example, if you're sick of writing for (int i=0; i<=10; i++) all the time, you can do the following:
#define fori10 for (int i=0; i<=10; i++)
// some code...
fori10 {
// do stuff to i
}
If you want something more generic, you can create preprocessor macros:
#define fori(x) for (int i=0; i<=x; i++)
// the x will be replaced by what ever is put into the parenthesis, such as
// 20 here
fori(20) {
// do more stuff to i
}
It's also very useful for conditional compilation (the other major use for #define) if you only want certain code used in some particular build:
// compile the following if debugging is turned on and defined
#ifdef DEBUG
// some code
#endif
Most compilers will allow you to define a macro from the command line (e.g. g++ -DDEBUG something.cpp), but you can also just put a define in your code like so:
#define DEBUG
Some resources:
Wikipedia article
C++ specific site
Documentation on GCC's preprocessor
Microsoft reference
C specific site (I don't think it's different from the C++ version though)
Mostly stylistic these days. When C was young, there was no such thing as a const variable. So if you used a variable instead of a #define, you had no guarantee that somebody somewhere wouldn't change the value of it, causing havoc throughout your program.
In the old days, FORTRAN passed even constants to subroutines by reference, and it was possible (and headache inducing) to change the value of a constant like '2' to be something different. One time, this happened in a program I was working on, and the only hint we had that something was wrong was we'd get an ABEND (abnormal end) when the program hit the STOP 999 that was supposed to end it normally.
I got in trouble at work one time. I was accused of using "magic numbers" in array declarations.
Like this:
int Marylyn[256], Ann[1024];
The company policy was to avoid these magic numbers because, it was explained to me, that these numbers were not portable; that they impeded easy maintenance. I argued that when I am reading the code, I want to know exactly how big the array is. I lost the argument and so, on a Friday afternoon I replaced the offending "magic numbers" with #defines, like this:
#define TWO_FIFTY_SIX 256
#define TEN_TWENTY_FOUR 1024
int Marylyn[TWO_FIFTY_SIX], Ann[TEN_TWENTY_FOUR];
On the following Monday afternoon I was called in and accused of having passive defiant tendencies.
#define can accomplish some jobs that normal C++ cannot, like guarding headers and other tasks. However, it definitely should not be used as a magic number- a static const should be used instead.
C didn't use to have consts, so #defines were the only way of providing constant values. Both C and C++ do have them now, so there is no point in using them, except when they are going to be tested with #ifdef/ifndef.
Most common use (other than to declare constants) is an include guard.
Define is evaluated before compilation by the pre-processor, while variables are referenced at run-time. This means you control how your application is built (not how it runs)
Here are a couple examples that use define which cannot be replaced by a variable:
#define min(i, j) (((i) < (j)) ? (i) : (j))
note this is evaluated by the pre-processor, not during runtime
http://msdn.microsoft.com/en-us/library/8fskxacy.aspx
The #define allows you to establish a value in a header that would otherwise compile to size-greater-than-zero. Your headers should not compile to size-greater-than-zero.
// File: MyFile.h
// This header will compile to size-zero.
#define TAX_RATE 0.625
// NO: static const double TAX_RATE = 0.625;
// NO: extern const double TAX_RATE; // WHAT IS THE VALUE?
EDIT: As Neil points out in the comment to this post, the explicit definition-with-value in the header would work for C++, but not C.

Over reliance on macros

I feel, every time I read a C or C++ program, that half or more of it is just macros. I understand that macros can be cool but they are hard to track, debug, etc. Not to mention that most programming languages do not even define something like macros (although Perl6 will have something of the sort).
I personally always have found a way to write my code without using macros, whether it be with templates, multiple inheritance, etc. I have even felt I am not a good programmer because all the pros use macros and I try to avoid them as much as I can.
The question is, are there problems which cannot be solved without macros? Are macros ultimately a good/bad practice? When should I consider using a macro?
Yes, here's one. When you need to add tracing code to your program in such a way that one configuration contains it and the other completely omits you have to use macros.
Something like:
#ifdef WITH_LOGGING
#define LOG( x ) DoLog( x )
#else
#define LOG( x )
#endif
now you use it this way:
LOG( L"Calling blahblahblah with " + getSomeStringHardToCompute() );
and in the configuration with WITH_LOGGING you have that code and otherwise it is completely omitted - not even present in the binary, and therefore
it doesn't help others analyze your program
you get a smaller binary
the program doesn't waste time fo logging at all
the compiler can produce better optimized code.
You've been looking at some bad C++ code. The places I use macros are limited to:
header guards
very occasional conditional compilation
a general exception throwing macro
a general debugging/logging output macro
I don't think those four can be avoided.
Straight from Scott Myer's Effective C++ -> 1
Given the availability of consts and inlines, your need for the preprocessor is reduced, but it's not completely eliminated. The day is far from near when you can abandon #include, and #ifdef/#ifndef continue to play important roles in controlling compilation. It's not yet time to retire the preprocessor, but you should definitely plan to start giving it longer and more frequent vacations.
Debug behaviour may be controlled with constant flags or debug functions. So here is my list of unavoidables:
Multiple inclusion protection.
Macros are the only way of symbol stringification. assert macro, compact realization of const string & stringify(enum category value);
Example:
const char* stringify(enum category value)
{
#define c(x) case x: return #x;
switch(value) {
c(CIRCLE)
c(RECTANGLE)
c(TRIANGLE)
default: return "UNKNOWN";
}
#undef c // the most important part
}
Macros, of course, are also useful when you want to generate code during preprocessing. While this can be avoided using templates (see this SO question and discussion - Are C++ Templates just Macros in disguise?), you can use macros if it makes the life of your users easier - see how the 'googletest' project (https://github.com/google/googletest/) uses macros effectively. You obviously don't want to use macros to generate code that needs debugging, use templates instead.
I think that C++'s templates and inline functions make macros pretty much avoidable.
The ubiquitousness of macros is probably due to the fact that there are many C++ programmers that used to be C programmers. Such people will probably be proficient at using macros (because it sometimes really is the best or only solution in pure C) and might not see any point in learning the more complicated C++ features if they already know how to solve the problem. At least in the open source world, there are many C converts, so you naturally meet C paradigms. I don't think that you're a bad programmer if you avoid such a feature, many people do, just like GOTOs.
C (and therefore C++) is an extremely flexible programming language. This is great, because everyone can develop his own distinct style and solve most problems in several different ways. This, however, can also be considered a problem. In my opinion not a problem that should be solved by the language but by establishing conventions.
There are many features in C++ that can be safely ignored. Maybe there are weird special occasions where such a feature would really be the best approach, but in most cases, you can live without:
Friend classes
Macros
GOTOs
And more.
IMO, a senior C++ programmer should be able to at least read them all fluently - yet I expect a good programmer to consider carefully when and if to use an infamous feature.
There are many problems that I can't solve without macros.
For instance, serialization/deserialization of some structs
#define STRUCT_DESCRIPTION structname(MyStruct) member(int,a) member(double,b) member(long, c)
#include "declare_serializable_struct.h" // declares struct itself and generates serialization/deserializaton code
#undef STRUCT_DESCRIPTION
( BOOST_PP_SEQUENCE may also be used)
Another example - dispatching a messages using message map, i.e. generating switch like this:
switch(message_type)
{
case msg1: on_msg1(msg); break;
case msg2: on_msg2(msg); break;
...
}
and generate handler method declarations on_msgX(msg) in the same time using some message description table ("map")
Personally, I try to avoiod macros when possible, but I didn't succeed in this way.
However, lambdas in c++0x allows to inline arbitrary code into "user-or-library-defined languge statements" such a foreach loops, so macro realm lose a significant part :)
Macros are a solution for conditional compiling (by ifdef and ifndef). Here is the examples:
1)
#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP
//...
#endif
2)
#ifdef __cplusplus
#define BEGIN extern "C" {
#define END }
#define NULL (0);
#else
#define BEGIN
#define END
#define NULL ((void*)0);
#endif
//-------------------------
BEGIN
void my_function(char* str);
END
//-------------------------
void my_function(char* str)
{
if(str != NULL)
{
//...
}
}
But inline functions and templates replaces other usages of macros in C++.
I tend to avoid using macros as much as possible because of their obvious safety / debugging issues, however there are times when macros offer something that no other facility within the language does as elegantly, in which case I prefer to use a macro just because it makes my life (and those of my fellow developers) easier.
For example, I have created an Enum class, which wraps an enum in a struct (scope) and adds some functionality:
possibility of iteration (which implies an order of the values)
conversion to / from string (handy to read/write to a file, write to logs)
In order to create the enum, I use a macro which will automatically generate the converter (to and from) and the vector for iteration.
Of course I could do without one, after all the macro is only for code generation. But doing without one would mean violating DRY, and in my little own preferences "DRY" > "Don't use macros". Because once debugged the macro is safe, whereas a DRY violation is a nightmare for maintenance.
Now, I am all for ditching this macro as soon as I find how not to violate DRY. Ideas are obviously welcome... and an external script is NOT better ;)
My 2 cents.
I try to avoid macros too, but to expand on the debugging, I have not found a way to print file name, function name, and line number when debugging.
I typically have a header file called DebugLog.h with the following Macro
#define DEBUG(debugMessage) \
printf("%s | %s [%d] - %s\n", __FILE__, __PRETTY_FUNCTION___, debugMessage);
Using:
DEBUG("Test")
will output something like:
main.cpp | foo(void)[20] - Test
You can adjust the macro for C++, and other debugging statements. It's also possible to modify the macro to send the resulting string to a logger.
I've started working at a telecom company. The product code base is about 20 years old, and has to support many legacy products, while also trying to avoid duplicate code. the language used is C++03. I find lots of contstructs similar to the following
ClassA::methodA(...)
{
// Common code
...
#if defined(PRODUCT_A) || defined(PRODUCT_B)
// Code for Product A or Product B
...
#elif defined(PRODUCT_C)
// Code for product C
...
#endif
// Common code
...
}
Horrible stuff, I agree. So far, we haven't been able to find a better solution. At least with this approach, we can understand what the code is supposed to do by simple code-reading.
The question is, are there problems which cannot be solved without macros?
No.
are macros ultimately a good/back practice? When should I consider to use a macro?
In languages which don't support or honor the inline keyword, macros are a great way to re-use code, but at the same time avoid the overhead of a function call in any code that is tightly looped enough for that to make a huge difference.
Your rant about code being littered with macros is probably justified. There are indeed hard to debug and in some cases to read. But they do come in useful in the very small number of cases where optimisation like this is truly warranted.
Note that as of C99, C can now do explicit inline functions using the inline keyword, which reduces the need for macros and even has advantages over using macros.
Programming language macros are good for what all macros are good for: avoiding typing the same things over and over again. So if you find yourself writing same pieces of code in many places, why not make a macro out of it? Especially if you're writing a library, using macros can make life easier for someone trying to use that library. Take a look at almost any GUI toolkit (Qt being one example). They all make extensive use of macros.