How to get the address of a variable stated in C Macro?
I a开发者_开发知识库m new to C and am trying some macro statements. I have a line like this:
#define write_data(src, TYPE, VALUE ) (write_implement(src, sizeof(TYPE), &(VALUE)))
And in a later function, I would like to use memcpy
to copy the VALUE
in another memory zone. Like this:
void write_implement (void* src, int size_of_type, void* value)
{
//whatever, just making the destination address from the source address
void* dest = src + 4096;
memcpy(dest, value, size_of_type);
}
The VALUE being passed in can be of any kind of data. That's why I am using void* to point to it and memcpy to copy the number of size of bytes.
But it doesn't work of course :)
This is how I call the function:
write_data(addr, int, i*3); // i is a whatever integer variable
GCC gives me this:
error: lvalue required as unary ‘&’ operand
Does anyone have any idea how to find the address of the variable being passed in to the macro in order to allow me to make use of the address for copying?
The later part of the macro can be changed (the "write_implement" and the parameters but not the "write_data" parameters). And the implementation part is also free to change.
If your compiler supports C99 compound literals, you can do this:
#define write_data(src, TYPE, VALUE) write_implement(src, sizeof(TYPE), &(TYPE){ VALUE })
How about this:
#define write_data(src, TYPE, VALUE ) { \
TYPE xxxx##__LINE__ = (VALUE); \
write_implement(src, sizeof(TYPE), &(xxxx##__LINE__)); \
}
It uses a somewhat "random" variable to store the value, before passing its address.
When you expand the macro, you get for the third parameter, &(i * 3)
, which makes no sense. You can take the address of a variable, but not of an anonymous expression result.
If you want to pass a value in using void*
to hold the type, then you'd better have an actual variable named to hold it.
int i = 5;
int j = i * 3;
write_data(addr, int, j);
I gotta say, though, to me calling the function directly is cleaner:
write_implementation(addr, sizeof(int), &j);
It's possible to do some C magic to make the macro call look the way you wanted, although I'd advise against it.
#define write_data(src,type,value) \
{type t = (value); write_implementation(src, sizeof(type), &t);}
write_data(addr, int, i*3);
And, as an aside, a C++ template would allow you to use the result of an expression the way you wanted as well, and a bit prettier (the key is the const ref).
template <typename T>
write_impl(T& dest, const T& src)
{
memcpy(&dest, &src, sizeof(T));
}
// 'int' is the default type of 5*3
int intResult;
write_impl(intResult, 5*3);
// 'double' is the default type of 5.1*4.7
double doubleResult;
write_impl(doubleResult, 5.1*4.7);
// otherwise, have to cast
long longResult
write_impl(longResult, (long)5*3);
精彩评论