G++ Unused Label Warning for Preprocessor Macro - c++

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.

Related

multiple lines macro in C

does anyone know why this is syntactically wrong?
Im trying to covert this
#define OUTS_FROM_FP(_fp, _argCount) ((u4*) ((u1*)SAVEAREA_FROM_FP(_fp) - sizeof(u4) * (_argCount)))
to this
#define OUTS_FROM_FP(_fp, _argCount) {\
((u4*) ((u1*)SAVEAREA_FROM_FP(_fp) - sizeof(u4) * (_argCount))); \
cout<<"Hello World"<<endl; \
}
outs = OUTS_FROM_FP(fp, vsrc1); --this is how it is being called
I get a lot of errors when running this: they start from statements that say that variables that were passed to the macro before are unused
Expanded, the original macro will look like this:
outs = ((u4*) ((u1*)SAVEAREA_FROM_FP(fp) - sizeof(u4) * (vsrc)));
That's (as far as I can tell as you didn't provide much context) valid code.
Your modified macro expands the same statement to this:
outs = { /* ... */ };
Your compiler gets all kinds of confused as you are attempting to assign a code block to a variable...
All the usual caveats regarding the use of macros in general aside, you could use the comma operator to get your modified macro "working":
#define OUTS_FROM_FP( _fp, _argCount ) \
cout << "Hello world\n", \
((u4*) ((u1*)SAVEAREA_FROM_FP(_fp) - sizeof(u4) * (_argCount)))
(The output is put first, as statements separated by the comma operator evaluate to the result of the last statement -- putting the output first makes the macro still evaluate to the same value as the original macro.)
All in all, you're probably better off turning that macro into a function.
Assuming that _fp and _argCount are variables or simple expressions, the original version is an expression of type u4*.
The second is more complicated. The braces make it a block, but syntactically you’re using it as an expression. This is not allowed in the C++ standard, but is supported by g++ and some other compilers. Since you say you’re using GCC, the value of this expression is the value of the last line of the block, which in this case is cout<<"Hello World"<<endl. If you were using a compiler which did not support statement expressions, you’d get a more confused syntax error.
I expect that unless you can convert an ostream to a u4 pointer (which, given what context we have, seems very unlikely), this won’t work. In this simple case, you can fix it by simply switching the order of the lines in the block. In a more complicated case, which I expect is the end goal, you probably would need to do something like
#define OUTS_FROM_FP(_fp, _argCount) {\
u4* result = ((u4*) ((u1*)SAVEAREA_FROM_FP(_fp) - sizeof(u4) * (_argCount))); \
cout<<"Hello World"<<endl; \
result; \
}
This saves the output of the macro to a temporary variable, does whatever calculations you want (which can change result), and then on the last line “returns” result outside the macro. This is less portable than DevSolar’s solution, but it works better if you need to create temporary variables, and in my opinion is more readable.
However, as others point out in the comments, there is little reason (at least that we can see) to keep this as a macro instead of converting it to a function. Functions are much more robust in a variety of ways. Reasons you might still want to keep it as a macro include the definition of SAVEAREA_FROM_FP changing or the types u4 and u1 being different in different places. Neither of these would not be good programming practice, but you can’t control what others have done before and I don’t know enough about Dalvik to say it isn’t the case.

A previously defined constant, given as macro argument, is considered as string literal

Let's say I have defined a macro which does this
#define MY_MACRO(NAME) \
std::string get##NAME() const \
{ \
return doSomething(#NAME); \
}
Where doSomething method signature will be something like this
std::string doSomething(const std::string& parameter);
This works pretty well when the NAME macro parameter has no dashes in it.
For example :
#define MY_MACRO(thisIsA_test) // Works
But, when I have a dash in my string (this can happen) it won't work because dashes are not allowed in method names
#define MY_MACRO(thisIsA-test) // does NOT WORK
I have tried to work it around this way
#define thisIsAtest "thisIsA-test"
#define MY_MACRO(thisIsAtest)
Everything compiles just fine and I have the getthisIsAtest method generated but unfortunately the macro is not resolved and "thisIsAtest" is kept as string literal.
In other words the doSomething parameter string value will be "thisIsAtest" whereas I was expecting "thisIsA-test".
To expand the macro argument, just use an indirection macro.
#define stringize_literal( x ) # x
#define stringize_expanded( x ) stringize_literal( x )
Your use-case:
return doSomething( stringize_expanded( NAME ) );
Now the method will be named with name of the macro, and the function will be called with the contents of the macro. Somewhat questionable in terms of organization, but there you have it.
Why it works:
By default, macro arguments are expanded before being substituted. So if you pass thisIsAtest to parameter NAME, the macro expansion will replace NAME with "thisIsA-test". The pre-expansion step does not apply when you use a preprocessor operator # or ## though.
In your original code, one use of NAME is subject to ## and the other is subject to # so the macro definition of thisIsAtest never gets used. I just introduced a macro stringize_expanded which introduces an artificial use of NAME (via x) which is not subject to an operator.
This is the idiomatic way to use # and ##, since the expansion is desired more often than the literal macro name. You do happen to want the default behavior for ## in this case, but it could be considered a case of poor encapsulation (as the name of an interface is used to produce output), if you wanted to apply real programming principles to the problem.
There's nothing to work around.
As you have said yourself, dashes are not valid in function names.
So, do not use them.

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.

Name variable Lua

I have the following code in Lua:
ABC:
test (X)
The test function is implemented in C + +. My problem is this: I need to know what the variable name passed as parameter (in this case X). In C + + only have access to the value of this variable, but I must know her name.
Help please
Functions are not passed variables; they are passed values. Variables are just locations that store values.
When you say X somewhere in your Lua code, that means to get the value from the variable X (note: it's actually more complicated than that, but I won't get into that here).
So when you say test(X), you're saying, "Get the value from the variable X and pass that value as the first parameter to the function test."
What it seems like you want to do is change the contents of X, right? You want to have the test function modify X in some way. Well, you can't really do that directly in Lua. Nor should you.
See, in Lua, you can return values from functions. And you can return multiple values. Even from C++ code, you can return multiple values. So whatever it is you wanted to store in X can just be returned:
X = test(X)
This way, the caller of the function decides what to do with the value, not the function itself. If the caller wants to modify the variable, that's fine. If the caller wants to stick it somewhere else, that's also fine. Your function should not care one way or the other.
Also, this allows the user to do things like test(5). Here, there is no variable; you just pass a value directly. That's one reason why functions cannot modify the "variable" that is passed; because it doesn't have to be a variable. Only values are passed, so the user could simply pass a literal value rather than one stored in a variable.
In short: you can't do it, and you shouldn't want to.
The correct answer is that Lua doesn't really support this, but there is the debug interface. See this question for the solution you're looking for. If you can't get a call to debug to work directly from C++, then wrap your function call with a Lua function that first extracts the debug results and then calls your C++ function.
If what you're after is a string representation of the argument, then you're kind of stuck in lua.
I'm thinking something like in C:
assert( x==y );
Which generates a nice message on failure. In C this is done through macros.
Something like this (untested and probably broken).
#define assert(X) if(!(X)) { printf("ASSERION FAILED: %s\n", #X ); abort(); }
Here #X means the string form of the arguments. In the example above that is "x==y". Note that this is subtly different from a variable name - its just the string used in the parser when expanding the macro.
Unfortunately there's no such corresponding functionality in lua. For my lua testing libraries I end up passing the stringified version as part of the expression, so in lua my code looks something like this:
assert( x==y, "x==y")
There may be ways to make this work as assert("x==y") using some kind of string evaluation and closure mechanism, but it seemed to tricky to be worth doing to me.
EDIT:
While this doesn't appear to be possible in pure lua, there's a patched version that does seem to support macros: http://lua-users.org/wiki/LuaMacros . They even have an example of a nicer assert.

C++ Preprocessor metaprogramming: obtaining an unique value?

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.