C++ macro - pass as "parameter" next word instead of in () - c++

This code:
#define DEREF(ptr) (*ptr)
MyClass *pClass = new MyClass;
DEREF(pClass).foo(); // equivalent of (*pClass).foo() or simply pClass->foo()
Can I configure the #define macro to accept the ptr parameter as the word that follows the macro instead of bracketed statement, so that I can do the following?:
DEREF pClass.foo();

No, C macros can only receive parameters inside brackets '()'

Can I configure the #define macro to accept the ptr parameter as the word that follows the macro
No. You can, however, write custom code preprocessor that will transform your code before passing it to C++ compiler. This is not really simple or practical but can be done. moc in qt 4 operates this way - scans for custom keywords and replaces them with C++ statements compiler can accept. This allows Qt 4 to implement its "signal/slot" mechanism.

Related

G++ Unused Label Warning for Preprocessor Macro

I'm working through compiler warnings in a project, attempting to clean up the code, and one warning/error that has confused me is an unused-label warning for the following code.
STATE(initialize)
It says that the "initialize" label is defined but not used. STATE is a #define macro that is as follows:
#define STATE(x) x: __TRACE__("enter", #x);
And the __TRACE__ macro is as follows:
#define __TRACE__(y,x) dbg.printf(DebugIO::debug2,"FSM:" y "(" x ")\n");
Note, I did not write this code, and am just working through a project attempting to correct as many warnings as possible. But from what I can tell, the initialize label is passed to __TRACE__ where it's used as an argument for a printf() call.
So, why is it not used? Does the compiler not look at preprocessor directives for variable usage?
How would I correct this?
from what I can tell, the initialize label is passed to __TRACE__ where it's used as an argument for a printf() call.
No, it is not, actually. The x parameter of STATE() is not the same as the x parameter of __TRACE__().
In the statement STATE(initialize), the x parameter is initialize, so x: becomes simply initialize: (the label in question), but #x stringifies the input value of x as "initialize" in this case, so STATE(initialize) expands to this:
initialize: __TRACE__("enter", "initialize");
And then, in the __TRACE__ macro, the y parameter is "enter" and the x parameter is "initialize", so __TRACE__("enter", "initialize") expands to this:
dbg.printf(DebugIO::debug2,"FSM:" "enter" "(" "initialize" ")\n");
And lastly, string literals that are separated by only whitespace are merged together by the compiler, so the final code for STATE(initialize) looks like this:
initialize: dbg.printf(DebugIO::debug2,"FSM:enter(initialize)\n");;
And since there is no goto or other statement that references the initialize label, that is why you get a warning about it.
How would I correct this?
Unless there is an actual goto initialize statement in the code somewhere, I would just get rid of the label altogether:
#define STATE(x) __TRACE__("enter", #x);
The very reason for the warning is the fact that
x: TRACE...
introduces the label to be used with goto. It bears to reason that there is no goto to initialize state (it looks like we are looking at FSM implementation).
There is probably no way to remove this warning without re-working the framework (for example, adding a special state macro which does not define a label for states you never get into), but one can also just silence this particular warning for the project.
Note that __attribute__((unused)) can be used on a label.
Converting the macro argument to a string doesn't count as "using" the label that happens to have the same name (remember that labels are a separate namespace from variables anyway, let alone macro arguments).
Using the (GCC extension) unary && operator to take the address of the label might also suppress the warning, but as a rule you should avoid anything that looks like a dynamic goto unless you really know what you're doing. So prefer the attribute version.
Note also that __TRACE__ is a reserved name since it contains 2 underscores next to each other.

Macro that calls different function based on parameter

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...

How to define a pattern in macro in C++?

I have a file having too many section like
[Section]
[Section.Ia32]
[Section.x64].... so more
so, I need to define single macro to when parsing the file we can get the section using one macro. currently I am trying like,
#define APattern = "(^(\\s)*\\[Section(\\.\\w+)*\\])";
it's compile succesfully... but it is not working.
For e.g
CString a = Section;
a.compareNoCase(APattern);
it is not working..
thanks
I think the syntax in your define is incorrect. In c++ a
define
is without
"=",
rather like
#define SQR(a) (a * a).
So in your define an argument is missing as well. Do not use the
";"
at the end of the line.
And for second, you are passing the result as an argument to the function
a.compareNoCase(),
which might be incorrect in meaning of which type is returned by your define.
With #define everything you have after the name is just pasted. So for yuor example the result will be:
CString a = Section;
a.compareNoCase( = "(^(\\s)*\\[Section(\\.\\w+)*\\])"; );
You can see for yourself it is invalid syntax. For correct definition you an go backwards:
a.compareNoCase( "(^(\\s)*\\[Section(\\.\\w+)*\\])" );
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-->
#define APattern "(^(\\s)*\\[Section(\\.\\w+)*\\])"
I think you have 2 problems, the first one, regarding C macro syntax, rightly addressed by fiscblog answer (+1), the other is that seems you are actually expecting a regular expression match, that is over CString capabilities. See for instance this answer to get regular expressions matching working in Visual C++
To be true, I would address the problem using sscanf, more or less like
#define ASection(In, Section) (sscanf(In, " [Section(%^[)])", Section) == 1)

Passing parameters to a no-op macro in C++

I am getting the following error message
error: '0' cannot be used as a function
when trying to compile the following line:
NOOP(0 != width);
NOOP is defined as follows:
#define NOOP (void)0
The source code is part of a SDK - so it should be okay. And I have found out that (void)0 actually is a valid way to descibe "no operation" in C++. But why would you want to pass a boolean parameter to a function which does nothing? And how do you get rid of the error message?
The MACRO is not defined with any parameters on it, so after the preprocessor replaces code, that statement ends up looking like this:
(void)0(0 != width);
Which confuses the compiler into thinking you are trying to use the "()" operator on 0. (i.e. using 0 as a function)
I recommend that you drop the "(0 != width)" (it is misleading) and just write NOOP;
"(void)0(0!=width);" is not valid C++, so it's not OK. (void)0; by itself doesn't do anything in C++, so can be used as a noop. Instead of your current define, I would use:
#define NOOP(X) (void)0
This tells the C++ preprocessor that there is a preprocessor function called NOOP that takes one parameter of any type, and replaces that entire function call with (void)0. So if you have a line of code that says NOOP("HELLO WORLD"), then the preprocessor replaces that entire thing with (void)0, which the C++ compiler proceeds to ignore.

What does "#define STR(a) #a" do?

I'm reading the phoneME's source code. It's a FOSS JavaME implementation. It's written in C++, and I stumbled upon this:
// Makes a string of the argument (which is not macro-expanded)
#define STR(a) #a
I know C and C++, but I never read something like this. What does the # in #a do?
Also, in the same file, there's:
// Makes a string of the macro expansion of a
#define XSTR(a) STR(a)
I mean, what's the use of defining a new macro, if all it does is calling an existing macro?
The source code is in https://phoneme.dev.java.net/source/browse/phoneme/releases/phoneme_feature-mr2-rel-b23/cldc/src/vm/share/utilities/GlobalDefinitions.hpp?rev=5525&view=markup. You can find it with a CTRL+F.
In the first definition, #a means to print the macro argument as a string. This will turn, e.g. STR(foo) into "foo", but it won't do macro-expansion on its arguments.
The second definition doesn't add anything to the first, but by passing its argument to another macro, it forces full macro expansion of its argument. So XSTR(expr) creates a string of expr with all macros fully expanded.
# is the stringizing operator. The preprocessor makes a string out of the parameter.
Say you have:
STR(MyClass);
It would be preprocessed as:
"MyClass";
The level of indirection (using XSTR()) has to do with macro expansion rules.
First, you should know that this pair of macros is actually fairly common. The first does exactly what the comment says -- it turns an argument into a string by enclosing it in double quotes.
The second is used to cause macro expansion of the argument. You typically use them together something like this:
#define a value_a
printf("%s", XSTR(a));
The macro expansion will expand a out to string_a, and the stringify will turn that into a string, so the output will be value_a.
The #a is referred to as the stringizer operator. It takes the formal parameter, in this case a, and turns it in to a string by enclosing it in double quotes.
So if you have:
string s = STR("my quoted string");
cout << s;
The output would be:
"my quoted string"