我是C新手,正在尝试一些宏观声明。我有这样一句话:
#define write_data(src, TYPE, VALUE ) (write_implement(src, sizeof(TYPE), &(VALUE)))
在稍后的函数中,我想使用memcpy
将VALUE
复制到另一个内存区域中。像这样:
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);
}
传入的VALUE可以是任何类型的数据。这就是为什么我使用void *指向它和memcpy来复制字节大小的数量。
但它当然不起作用:)
这就是我调用函数的方式:
write_data(addr, int, i*3); // i is a whatever integer variable
GCC给了我这个:
错误:左值作为一元'&'操作数
有没有人知道如何找到传入宏的变量的地址,以便我可以使用该地址进行复制?
可以更改宏的后半部分(“write_implement”和参数,但不能更改“write_data”参数)。实施部分也可以自由改变。
答案 0 :(得分:5)
如果您的编译器支持C99复合文字,您可以这样做:
#define write_data(src, TYPE, VALUE) write_implement(src, sizeof(TYPE), &(TYPE){ VALUE })
答案 1 :(得分:1)
这个怎么样:
#define write_data(src, TYPE, VALUE ) { \
TYPE xxxx##__LINE__ = (VALUE); \
write_implement(src, sizeof(TYPE), &(xxxx##__LINE__)); \
}
在传递地址之前,它使用一个稍微“随机”的变量来存储值。
答案 2 :(得分:0)
当您展开宏时,您将获得第三个参数&(i * 3)
,这是没有意义的。您可以获取变量的地址,但不能获取匿名表达式结果。
如果你想使用void*
传递一个值来保存类型,那么你最好有一个实际的变量来保存它。
int i = 5;
int j = i * 3;
write_data(addr, int, j);
但我必须说,对我来说直接调用该功能更清晰:
write_implementation(addr, sizeof(int), &j);
有可能做一些C魔法使宏调用看起来像你想要的方式,虽然我建议反对它。
#define write_data(src,type,value) \
{type t = (value); write_implementation(src, sizeof(type), &t);}
write_data(addr, int, i*3);
而且,顺便说一下,C ++模板允许你以你想要的方式使用表达式的结果,并且有点漂亮(关键是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);