Passing parameters to a no-op macro in C++ - 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.

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.

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)

C++ macro and default arguments in function

Im trying to make a generic function to display error messages, with the possibility that the program should exit after the message has been displayed.
I want the function to show the source file and line at which the error occurred.
argument list:
1.char *desc //description of the error
2.char *file_name //source file from which the function has been called
3.u_int line //line at which the function has been called
4.bool bexit=false //true if the program should exit after displaying the error
5.int code=0 //exit code
Because of (4) and (5) i need to use default arguments in the function definition, since i don't want them to be specified unless the program should exit.
Because of (2) and (3) i need to use a macro that redirects to the raw function, like this one:
#define Error(desc, ???) _Error(desc,__FILE,__LINE__, ???)
The problem is that i don't see how those 2 elements should work together.
Example of how it should look like:
if(!RegisterClassEx(&wndcls))
Error("Failed to register class",true,1); //displays the error and exits with exit code 1
if(!p)
Error("Invalid pointer"); //displays the error and continues
You cannot overload macros in C99 -- you will need two different macros. With C11, there is some hope using _Generic.
I had developed something very similar -- a custom warning generator snippet for Visual Studio -- using macros. GNU GCC has some similar settings for compatibility with MSVS.
#define STR2(x) #x
#define STR1(x) STR2(x)
#define LOC __FILE__ “(“STR1(__LINE__)”) : Warning Msg: “
#define ERROR_BUILDER(x) printf(__FILE__ " (“STR1(__LINE__)”) : Error Msg: ” __FUNCTION__ ” requires ” #x)
The above lines take care of your arguments 1 to 3. Adding support for 4 would require inserting a exit() call within the macro. Also, create two different macro wrappers should you require to two different argument lists (the one with the default argument can delegate to the other macro).
#define ERROR_AND_EXIT(msg, cond, errorcode) ERROR_BUILDER(msg) if (cond) exit(errorcode)
#define ERROR_AND_CONT(msg) ERROR_BUILDER(msg)
I had put up a detailed description here (warning: that's my blog -- so consider it to be a shameless plug).

Is it possible to make the execution of a program skip fprintf-statements/How to create my own fprintf-function?

In my C++-code there are several fprintf-statements, which I have used for debugging. Since I might need them again, I would prefer not to comment them out for the moment.
However, I need the execution of the program to be fast, so I would like to avoid them being printed out, as they are for the moment (I redirected stderr to a file).
Preferably this would be determined by the user passing an argument to the program, which I would extract like this:
main (int argc, char *argv[])
{
int isPrint=0;
if (argc > 1 ) {
isPrint = atoi ( argv[2]);
}
}
I thought of renaming fprintf to another name, and then from that function do a fprintf-call using the same parameters, based on the value of isPrint; however, then I realized that fprintf can have so many different kind of arguments and a various number of arguments; and that I don't know any generic way of declaring my own function with those requirements.
So I wonder how to create a function,which works exactly like fprintf, but which takes the extra parameter isPrint; or how to solve the above problem in another way.
Complementary information after first post:
One solution would be to add this before each fprintf-statement:
if (isPrint == true )
The typical approach is to use the preprocessor to compile away the calls to fprintf().
You would do something like this:
#if defined DEBUG
#define LOG(a) fprintf a
#else
#define LOG(a)
#endif
And in the code you would do:
LOG(("The value is %f", some_variable));
Note the double parenthesis, that's just to make the syntax work. You can do it nicer, but this is simpler to explain.
Now, you would either just edit the code to #define or #undef the DEBUG preprocessor symbol at the top of the file, or pass suitable options to the compiler (-D for GCC).
First note that if this is just for debugging, I'd agree that the typical way is to use macros or preprocessor defines to tell the compiler to include logging or not.
However, if you don't want it removed entirely by the compiler (so that you can turn the printing on or off with an argument), you could write your own log function that takes isPrint and some string, and then use snprintf() to format the string before you call it.
Something along these lines:
void myLog(int isPrint, char *message)
{
if(isPrint == 1)
{
fprintf(logFile, "%s", message);
}
}
char msg[64];
snprintf(msg, 64, "Test Message %d", 10);
myLog(isPrint, msg);
It may also be possible to wrap fprintf() in your own varags function, but that would be more complicated.
For debugging purpose you can use the variable argument macro:
#ifdef DEBUG
#define FPRINTF(...) fprintf(__VA_ARGS__)
#else
#define FPRINTF(...)
#endif
Be attentive that, if you use fprintf directly instead of FPRINTF then since you are defining a library function, it should appear after #include<> of that function.
It depends how much flexibilty you've got in changing the code and whether you want to be able to switch this off at runtime or just compile time.
I'd suggest you wrap it in your own variadic function (for tips look here) and then you've encapsulated the functionality.
Your function will essentially be just a thin wrapper round fprintf() but at this point you can then either use the preprocessor to ensure that your logging function does nothing if you compile it out, or you can do an integer comparison with, say, a logging level at runtime so that the underlying fprintf() only gets called if your debugging level is high enough.

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

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.