#define Te0 (u32)((u64*)((u8*)Te+0))
#define Te1 (u32)((u64*)((u8*)Te+3))
#define Te2 (u32)((u64*)((u8*)Te+2))
#define Te3 (u32)((u64*)((u8*)Te+1))
static const u64 Te[256] = {
U64(0xa56363c6a56363c6), U64(0x847c7cf8847c7cf8),
.....}
具有此示例C代码,其中数组Te0,Te1,Te2和Te3定义为宏,而Te定义为使用256无符号长long值初始化的静态数组。
我理解Te数组,有效索引是0-255,我可以打印Te数组第i个元素的地址作为& Te [i]
当我尝试将地址打印为& Te0 [0]时,它会抛出错误
error: lvalue required as unary ‘&’ operand
我有关于宏样式定义数组的以下问题。
我在linux中使用gcc。
谢谢
EDIT-1:我同意,宏在编译时被扩展,但是当运行时知道s0和s1时,怀疑后面的表达式是如何正确计算的(s0和s1的值不同)在不同的运行)和编译时完成的宏扩展?
t[0] = Td0[(s0 ) & 0xff] ^
Td1[(s3 >> 8) & 0xff]
答案 0 :(得分:0)
请注意(u32)((u64*)((u8*)Te+0))
不 l-value(但演员可能会丢失信息),因此您无法获取其地址(同样地,您无法取得地址)一元减去)
你需要一些像
这样的中间步骤 #define TTe0 (*((u8*)Te+0))
然后你可以写&TTe0
如果您有许多类似于#define Te0
的宏定义,您可以编写一些脚本(可能使用sed
或awk
)来生成包含此类#define TTe0
的标头,然后包括适当的。
请记住,可以生成C代码(所以头文件)!然后,您可以为此目的调整构建过程(例如,编辑一些Makefile
)。
详细了解C preprocessor,特别是documentation。您可以使用gcc -C -E
(关于你的其他问题,请阅读一本好的C编程书,然后阅读C11标准即n1570;一旦预处理确实发生,表达式来自某些宏扩展的事实就无关紧要了,编译器主要看到预处理的形式)
你的问题有一个误导性的标题:这不是通过一个宏来获取地址,而是取一些演员的地址,这显然毫无意义。
您可以通过宏获取地址。一个典型的例子是&errno
,因为errno(3)是一个宏(在内部头文件/usr/include/bits/errno.h
中定义,它通过<errno.h>
标准头包含在内。