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.
Related
I have the following method for various test cases:
test_case(mystruct->myvar1, "myvar1", ...);
test_case(mystruct->myvar2, "myvar2", ...);
test_case(mystruct->myvar3, "myvar3", ...);
Is there a way i can avoid having to type myvar1 twice, once as the variable and once as a string. ?
Sure there is.
The question is is that a good idea?
#define MY_TEST(object, value, ...) do { test_case(object->value, #value , __VARARGS__); } while(false)
Code:
MY_TEST(mystruct, myvar1, ...);
MY_TEST(mystruct, myvar2, ...);
MY_TEST(mystruct, myvar3, ...);
Excplanation:
In the macro:
#define MY_TEST(object, value, ...)
The words: object and value become parameters to the macro. And are replaced identically in the expression on the right. If a parameter is prefixed with # then it is stringified by adding double quotes around it.
object->value, #value => object->value, "value"
Macros can also have a variable argument list represented by the ... which is replaced by using __VARARGS__ on the destination side. There is one limitation with using varargs in that it must match at least one parameter (i.e it can not match zero parameters (they may have fixed that but not sure)).
The reason to add the do { ... } while(false) is me being pedantic when using macros to make sure that the expression is treated like a statement. The compiler will optimize this away so there is no extra code and the statement is executed exactly once. I find it good practice to be overly careful and pedantic when using macros as there is little protection from the pre-processor (and the language has tried to evolve away from using macros in the first place).
You can use stringify:
#define F(a) a, #a
F(x) // x, "x"
I need to convert an expression to its result before applying it on a preprocessor. This is probably a simple problem, but I couldn't figure out a way to do it.
My preprocessor is like this:
#define ABCD(BITPOS) \
if(BIT##BITPOS##_MASK & 0x01) { \
Do something; }
And BIT0_MASK to BIT100_MASK is defined at some place.
If I call ABCD(5), preprocessor converts it to BIT5_MASK and it works fine.
But, I want to call it like this:
ABCD(START_VAL+2),
it gives me compilation error saying BITSTART_VAL is not declared, )_MASK is not defined and whole bunch of related errors.
How can I make it work ? Appreciate your responses.
The preprocessor macro system cannot evaluate arithmetic operators. It can only splice tokens together and substitute identifiers.
You will need to find another solution.
If you really really must do this, the folks at Boost created macros to perform some basic arithmetic, using only splicing and substitution as a basis. That is not an appropriate tool for this job, though.
Looks like you need an inline function rather than a macro.
inline size_t ABCD(unsigned int bitmask)
{
if (bitmask & 0x01U)
{
something();
}
}
The inline keyword will hint to the compiler that you want the code to be pasted rather than called.
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.
Reading some C++ code I came across what I'll call a "functional" use of function Macros roughly as follows (this is a totally stylized example to make the point):
#define TOP_LEVEL(ARG1) \
ARG1("foo1","bar1") \
ARG1("foo2","bar2")
#define NEXT_LEVEL(ARG2A, ARG2B) \
cout << ARG2A << " and " << ARG2B;
TOP_LEVEL(NEXT_LEVEL)
I'm relatively new to the language and at first I couldn't figure this out, but then I ran it through just the preprocessor (g++ -E) and lo and behold it resolves to:
cout << "foo1" << " and " << "bar1"; cout << "foo2" << " and " << "bar2";
Do you see what it did there? It passed the Macro NEXT_LEVEL like a function pointer to the Macro TOP_LEVEL. Seeing how useful this could potentially be, I wanted to learn more about it: passing around functions to other functions is pretty sophisticated stuff and there must be at least something more to say about the technique.
Yet despite a ton of Googling I can't find evidence that this feature of the preprocessor even exists, let alone anything approaching documentation: here, here, here and here are just four examples of Macro tutorials that skip right past this; the last even has a section called "Advanced Macro tricks" - surely this qualifies!?
(Please note this is totally different than simply calling a function macro with another evaluated function macro as an argument- FOO(BAR(2)) is much more straightforward.)
My questions are:
Is there an actual name for this behavior?
Is it documented anywhere?
It is commonly used, or are there well known pitfalls, etc.?
The idea is coined "X-Macro". Some definitions won't include your particular example (X-macros generally are a bit more involved, with a file being included), but any relevant info. about this will fall under that term when searching.
As chris mentioned in the comments, Boost.Preprocessor uses this idea to great effect. Popular uses are: BOOST_PP_REPEAT, BOOST_PP_LIST_FOR_EACH, and most powerfully: BOOST_PP_ITERATE.
BOOST_PP_ITERATE is a "true" X-Macro; including a single file is expands to something dependent on a macro defined just prior. I show a more "proper" skeleton framework in this other answer, but an example would be:
// in xyz_data.def
DEFINE_XYZ(foo, 1, "Description A")
DEFINE_XYZ(bar, 5, "Description B")
DEFINE_XYZ(baz, 7, "Description C")
Then later when I just want column 1 I can do:
#define DEFINE_XYZ(name, number, desc) some_func(name)
#include "xyz_data.def"
And somewhere else where I want to generate some function for each one, I can do:
#define DEFINE_XYZ(name, number, desc) \
int BOOST_PP_CAT(get_number_for_, name)() \
{ \
std::clog << "Getting number, which is: " desc << std::endl; \
\
return number; \
}
#include "xyz_data.def"
You can then generate an enum where the name equals the number, etc.
The power is that when I want to add a new xyz, I just add it in one spot and it magically shows up everywhere it needs to be. I have done something like this in a very large codebase to keep some bookmarking data in one central place, but the various attributes were used differently in various locations.
Note that there is often no way around this; what I have are syntactically different, so no other language feature will generalize it for me to that level, only macros. Macros are not evil.
What you have is effectively an X-macro where the .def file is self-contained enough to be a #define. In other words, #include "xyz_data.def" is just TOP_LEVEL.
There is only one large downside to this, and ironically it's not the use of X-macros themselves but the effect they have on C and C++ compilers. The problem is that the preprocessor has allowed us to change the preprocessed result of a file every time its included, even if the file contents are exactly the same.
You may have heard that C and C++ are slow to compile compared to modern languages, this is one of the reasons why. It has no proper module/packaging system, just ad-hoc inclusion of other files. And we just learned, in general this cannot be avoided. Oops. (That said, compilers are smart and will note when you have include guards around a file, for example, and avoid processing it multiple times. But this is situational.)
That said, using X-Macros themselves shouldn't be a huge contributor to the compilation time of a real program. It's just that their mere potential existence reaches out into the real word and screws with compiler's heads.
Here is a few lectures : C is purely functionnal,
I suggest you take a look at libpp, macrofun,
I was assigned the task of updating a very old project a while back. The first thing I had to do was to expand the existing code to incorporate a new feature. As part of this I modified existing macros to print JSON representations of incoming messages (over CORBA, into C++ structs). I then incorporated boost program_options and a new logger and now I want to modernise the macros.
The problem is that I have no idea how to implement what I did with the macros with templates. The key problem is that I use the name of the parameters to the macros to access the fields of the struct:
//Defines the string that precedes the variable name in a JSON name-value pair (newline,indent,")
#define JSON_PRE_VNAME _T("%s,\n\t\t\t\t\"")
//Defines the string that follows the variable name in a JSON name-value pair (":) preceding the value
#define JSON_SEP _T("\":")
#define printHex(Y,X) _tprintf(_T("%02X"), (unsigned char)##Y->##X );
// ******** MACRO **********
// printParam (StructureFieldName=X, ParamType=Y)
// prints out a json key value pair.
// e.g. printParam(AgentId, %s) will print "AgentId":"3910"
// e.g. printParam(TempAgent, %d) will print "TempAgent":1
#define printParam(X,Y) if(strcmp(#Y,"%s")==0){\
_byteCount += _stprintf(_logBuf,JSON_PRE_VNAME _T(#X) JSON_SEP _T("\"%s\""),_logBuf,myEvent->##X);\
}else{\
_byteCount += _stprintf(_logBuf,JSON_PRE_VNAME _T(#X) JSON_SEP _T(#Y),_logBuf,myEvent->##X);\
}\
printBufToLog();
And it is used like this:
//CORBA EVENT AS STRUCT "event"
else if(event.type == NI_eventSendInformationToHost ){
evSendInformationToHost *myEvent;
event.data >>= myEvent; //demarshall
printParam(EventTime,%d);
printParam(Id,%d);
printParam(NodeId,%d);
}
and this results in JSON like this:
"EventTime":1299239194,
"Id":1234567,
"NodeId":3
etc...
Obviously I have commented these macros fairly well, but I am hoping that for the sake of anyone else looking at the code that there is a nice way to achieve the same result with templates. I have to say the macros do make it very easy to add new events to the message logger.
Basically how do I do "#X" and ##X with templates?
Any pointers would be appreciated.
Thanks!
There are some things that you cannot really do without macros, and for some specific contexts macros are the solution. I would just leave the macros as they are and move on to the next task.
Well, I would actually try to improve a bit the macros. It is usually recommended not to use ; inside macros, and with macros that contain more than a single statement wrap them in do {} while(0) loops:
#define printHex(Y,X) _tprintf(_T("%02X"), (unsigned char)##Y->##X )
// remove ; ^
// add do while here:
#define printParam(X,Y) do { if(strcmp(#Y,"%s")==0){\
_byteCount += _stprintf(_logBuf,JSON_PRE_VNAME _T(#X) JSON_SEP _T("\"%s\""),_logBuf,myEvent->##X);\
}else{\
_byteCount += _stprintf(_logBuf,JSON_PRE_VNAME _T(#X) JSON_SEP _T(#Y),_logBuf,myEvent->##X);\
}\
printBufToLog();\
} while (false)
This might help avoid small mistakes that would otherwise be hard to fix, as, for example uses of the macros with if:
if (condition) printHex(a,b);
else printHex(c,d);
// looks good, but would originally expand to a syntax error:
if (condition) _tprintf(_T("%02X"), (unsigned char)##Y->##X );;
else ...
Similarly
if (condition) printParam(a,b);
else ...
would expand to a whole lot of non-sense for the compiler even if it looks correct enough to the casual eye.
I think that in many cases it's better to use an external code generator... starting from a nice neutral definition it's easy to generate C++, Javascript and whatnot to handle your data.
C++ templates are quite primitive and structure/class introspection is just absent. By playing some tricks you can be able to do ifs and loops (wow! what an accomplishment) but a lot of useful techniques are just out of reach. Also once you get your hard to debug template trickery working, at the first error the programmer makes you get screens and screens of babbling nonsense instead of a clear error message.
On the other side you have the C preprocessor, that is horribly weak at doing any real processing and is just a little more (and also less) than a regexp search/replace.
Why clinging to poor tools instead of just implementing a separate code generation phase (that can easily be integrated in the make process) where you can use a serious language of your choice able to do both processing and text manipulation easily?
How easy would be to write a neutral easy-to-parse file and then using for example a Python program to generate the C++ struct declarations, the serialization code and also the javascript counterpart for that?