I'm reading some Fortran 90 code and come across some concepts that I'm not familiar with.
Part of the code, which is defined to calculate dot product of two vectors, dmf_dotp for real value, zmf_dotp for complex ones.
mesh.F90:
#include mesh_inc.F90
interface dmf_dotp
module procedure dmf_dotp_1, dmf_dotp_2
end interface dmf_dotp
interface zmf_dotp
module procedure zmf_dotp_1, zmf_dotp_2
end interface zmf_dotp
In another file there are functions like:
R_TYPE function X(mf_dotp_1)(mesh, f1, f2, reduce, dotu) result(dotp)
R_TYPE function X(mf_dotp_2)(mesh, dim, f1, f2, reduce, dotu) result(dotp)
Then one can call these functions(or interfaces?) with zmf_dotp or dmf_dotp. So what's really going on here?
Edit thanks to Vladimir F. It turns out there are some preprocessor macros defined else:
#define X(x) z ## x
#define R_TYPE CMPLX
This is one of the ways one can do generic programming in Fortran without copy and paste everything.
I assume it actually looks similar to:
#define X(x) z ## x
#define R_TYPE CMPLX
#include mesh_inc.F90
and
#define X(x) d ## x
#define R_TYPE FLOAT
#include mesh_inc.F90
or similar, it seems that CMPLX is another macro which leads to some kind of complex and therefore I expect FLOAT to be some kind of real, possibly double precision.
This will actually lead for the preprocessed source code as
double precision function dmf_dotp_1(...)
and
double complex function zmf_dotp_1(...)
with the functions having similar or even identical body.
This enables you to write the relevant code only once and create reuse with under different names with different types.
Beware! The very popular gfortran compiler runs the C preprocessor in the "traditional mode" which does not support the ## operator.
Related
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++.
Hello all I was having trouble with macros so I thought I would practice and I was looking at the ## macro operator and thought I could use it for my problem I wan't to be able to call multiple functions based on the parameter for example if I have a macro like so:
#define macro(a) func##a();
int main()
{
.....
for(int i = 0;i< length;i++)
{
macro(i)
}
func1()
{
}
....
func31()
{
}
Anyone have an idea of how I can accomplish this??
You can only combine two preprocessor tokens. However, func isn't a preprocessor token. You need to jump through an extra hoop, calling some form of "concat" macro:
#define CONCAT(a, b) a ## b
#define macro(a) CONCAT(func,a)
Of course, the tokens produced by you macro won't be func1, ..., func31 (of course, they would also need to start with func0 if your logic were correct) but rather funci. The expansion of macros happens at the beginning of compilation while the execution of the for-loop happens at run-time (some optimizations may hoist it into compile-time but that won't affect the macros).
If you need to expand a sequence of integers in combination with a macro, you may want to have a look at the Boost preprocessor library, in particular at the BOOST_PP_REPEAT functionality.
If you just need to statically expand a sequence of integers to function calls, you might also consider looking at function template templatized on an integers: I would certainly consider using an approach using templates before trying to use the preprocessor library...
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
As far as I know, macros rearrange the program text before the compiler even sees it properly, thus potentially causing problems. I hardly ever see them in C++ code, mostly in C.
The only good use I know of, is inclusion guards (#ifndef).
Is there anything else that needs to be done with macros and cannot be implemented in a cleaner way?
Logging and Exception.
A macro allows you to effortlessly capture __FILE__, __LINE__ and __func__. Oh sure you could write them manually each time, but frankly this is tedious and error prone (both __FILE__ and __func__ are C-string so you risk mixing them up).
Prior to C++11, you would usually define static_assert as a macro (a typedef that would be invalid if the condition is false), so it can be available from anywhere (namespace level, or function level) and still not be ambiguous (e.g. by using a line number).
The Boost.Preprocessor library is another good example of using macros to reduce the amount of highly redundant code, and another one that is less relevant with variadic templates.
Furthermore macros are widely used to "talk" to the compiler, e.g. checking what compiler you are running on, what version of the compiler, whether C++11 support is available, etc.
Yes, the X-macro trick will always be useful.
You put your data in one header (no #include guards!), then use a macro to conditionally expand it.
Example:
Data.h:
X(Option1, "Description of option 1", int, long)
X(Option2, "Description of option 2", double, short)
X(Option3, "Description of option 3", wchar_t*, char *)
MyProgram.cpp:
enum Options
{
#define X(Option, Description, Arg1, Arg2) Option,
# include "Data.h"
#undef X
};
char const *descriptions[] =
{
#define X(Option, Description, Arg1, Arg2) Description,
# include "Data.h"
#undef X
};
#define X(Option, Description, Arg1, Arg2) typedef void (*P##Option)(Arg1, Arg2);
# include "Data.h"
#undef X
It's not the prettiest sight, but it avoids code duplication and lets you keep everything in one place.
Macros can be defined from the compiler command line, with -DFOO, which would define the macro FOO. This is most often used for conditional compilation, e.g. a certain optimization that is known to work on some platforms but not on others. The build system can detect whether the optimization is viable an enable it using this kind of macro.
This is one of the few uses of macros that I believe can be used well. However, it's of course possible to abuse this feature as well.
The macros are considered error prone due to its characteristics, here we have some good examples of error prone macros:
Macros VS inline functions.
Macros containing if.
Multiple line macros.
Concatenation macros.
But they could be useful in some ways, for example, in order to make te code more readable when dealing with function pointers:
class Fred {
public:
int f(char x, float y);
int g(char x, float y);
int h(char x, float y);
int i(char x, float y);
// ...
};
// FredMemberFn points to a member of Fred that takes (char,float)
typedef int (Fred::*FredMemberFn)(char x, float y);
// Useful macro:
#define callMemberFunction(object,ptrToMember) ((object).*(ptrToMember))
With the "Useful macro", you can call function pointers like this:
callMemberFunction(fred,memFn)('x', 3.14);
That is slightly more clear than:
(fred.*memFn)('x', 3.14);
Credits: C++ FAQ Lite.
Several uses (some may have been mentioned already..)
Logging: DEBUG(....), this is neat because the contents are only evaluated if the logging is active (so the macro could have a test for log level for example...) You cannot replace this with an inline function as the arguments will always be evaluated. However with c++11, there is a lambda trick which will avoid the evaluation, however the syntnax is cludgy so you'll end requiring a macro anyway to clean it up! :)
Code generation, I use lots of SFINAE tests, and it's easy to generate the test with a couple of macros rather than hand construct the test every time.
There are some code rewriting for optimization that seem not to be doable with template metaprogramming and need macros. Here is a probable example: C++ template for unrolling a loop using a switch?
Yes, they will still have uses such as for "message maps" in ATL, WTL, MFC.
For example, this is part of some personal code I have:
BEGIN_MSG_MAP(This)
MESSAGE_HANDLER(WM_CLOSE, OnClose)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
MESSAGE_HANDLER(WM_GETDLGCODE, OnGetDlgCode)
COMMAND_RANGE_HANDLER(IDOK, IDNO, OnButtonClick)
CHAIN_MSG_MAP(CDialogResize<This>)
END_MSG_MAP()
Or even specifying the layout of a window:
BEGIN_DLGRESIZE_MAP(This)
DLGRESIZE_CONTROL(IDOK, DLSZ_MOVE_X)
DLGRESIZE_CONTROL(IDCANCEL, DLSZ_MOVE_X)
DLGRESIZE_CONTROL(IDC_EDITINPUT, DLSZ_SIZE_X)
END_DLGRESIZE_MAP()
Writing this without macros would involve a lot of unnecessary boilerplate code.
When you need to utilize platform, compiler, or implementation specific features. Typically, this is either to improve portability or to access features which are expressed differently in the systems you target (i.e. it may be written differently on the compilers you use).
And expanding on Matthieu's answer (+1): Assertions.
Writing exception-checking tests with macros is much easier than with functions.
#define TEST_THROWS(code) do { try { code; } catch (...) { pass(); } fail(); } while(0)
Note: example not tested
Extending on the answer from #Matthieu, I've used macros to add file and line logging to a legacy codebase. So this:
void MovePlayer(Vector3 position)
{
...
}
became something like:
#define MovePlayer(pos) MovePlayer_(pos, __FILE__, __LINE__)
void MovePlayer_(Vector3 position, const char* file, int line)
{
LogFunctionCall("MovePlayer", file, line);
...
}
By only changing one place in the codebase, I was able to log everywhere that the function got called during a complex test. If you do this to enough functions, it's very useful for tracing existing behaviour in old codebases.
I have a CPU sensitive application and want to minimize function calls. I want to write something like:
#ifdef condition
#define f(a,b) ff(a,b)
#define f(a) ff(a)
#endif
But the compiler sees f as defined multiple times. I wanted to use __VAR_ARGS__ but in the example above b is of enum type. Is there a proper way to do it or I should just rename f(a,b) to f2(a,b)?
To clarify the defines, if active, add calls to functions that process data for printing to file/stdout, otherwise they are replaced with empty lines, so in my opinion this method would improve code size and since the macro is single line keyword like INFO(object->contents) I think it's more readable. Also it would have been useful if I could have added something like WARN("message") and WARN("value is",obj->printvalue()).
I also think inline would do the trick (from the answer below).
This is a very C-ish way of approaching this. Simply make it an overloaded inline function. Any optimiser worthy of the name will inline the call.
My first guess is that you are optimizing in the wrong areas. Good compilers will optimize in this case. Obfuscating code will make it harder for the compiler to do so.
Found the answer from the c++ book:
Macro names cannot be overloaded:
#define PRINT(a ,b ) cout <<(a )<<(b )
#define PRINT (a ,b ,c ) cout <<(a )<<(b )<<(c ) /* trouble?: redefines, does not overload */
I'm exploiting the behavior of the constructors of C++ global variables to run code at startup in a simple manner. It's a very easy concept but a little difficult to explain so let me just paste the code:
struct _LuaVariableRegistration
{
template<class T>
_LuaVariableRegistration(const char* lua_name, const T& c_name) {
/* ... This code will be ran at startup; it temporarily saves lua_name and c_name in a std::map and when Lua is loaded it will register all temporarily global variables in Lua. */
}
};
However manually instantiating that super ugly class every time one wants to register a Lua global variable is cumbersome; that's why I created the following macro:
#define LUA_GLOBAL(lua_name, c_name) static Snow::_LuaVariableRegistration _____LuaGlobal ## c_name (lua_name, c_name);
So all you have to do is put that in the global scope of a cpp file and everything works perfectly:
LUA_GLOBAL("LuaIsCool", true);
There you go! Now in Lua LuaIsCool will be a variable initialized to true!
But, here is the problem:
LUA_GLOBAL("ACCESS_NONE", Access::None);
Which becomes:
static Snow::_LuaVariableRegistration _____LuaGlobalAccess::None ("ACCESS_NONE", &Access::None);
:((
I need to concatenate c_name in the macro or it will complain about two variables with the same name; I tried replacing it with __LINE__ but it actually becomes _____LuaGlobalAccess__LINE__ (ie it doesn't get replaced).
So, is there a way to somehow obtain an unique string, or any other workaround?
PS: Yes I know names that begin with _ are reserved; I use them anyway for purposes like this being careful to pick names that the standard library is extremely unlikely to ever use. Additionally they are in a namespace.
You need to add an extra layer of macros to make the preprocessor do the right thing:
#define TOKENPASTE(x, y) x ## y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define LUA_GLOBAL(lua_name, c_name) ... TOKENPASTE2(_luaGlobal, __LINE__) ...
Some compilers also support the __COUNTER__ macro, which expands to a new, unique integer every time it is evaluated, so you can use that in place of __LINE__ to generate unique identifiers. I'm not sure if it's valid ISO C, although gcc accepts its use with the -ansi -pedantic options.