如何在linux中找到C中定义为宏的数组元素的地址

时间:2017-09-14 05:01:04

标签: c arrays linux macros

#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

我有关于宏样式定义数组的以下问题。

  1. Te0数组的有效索引是什么? Te1阵列?
  2. 什么是开始& Te0阵列的结束地址? Te1阵列?
  3. 如何计算和打印Te0数组第i个元素的地址& Te0 [i]会抛出错误?
  4. 数组宏定义中(Td + 0),(Td + 1),(Td + 3)的含义是什么?
  5. 我在linux中使用gcc。

    谢谢

    EDIT-1:我同意,宏在编译时被扩展,但是当运行时知道s0和s1时,怀疑后面的表达式是如何正确计算的(s0和s1的值不同)在不同的运行)和编译时完成的宏扩展?

    t[0] =  Td0[(s0      ) & 0xff] ^
            Td1[(s3 >>  8) & 0xff] 
    

1 个答案:

答案 0 :(得分:0)

请注意(u32)((u64*)((u8*)Te+0)) l-value(但演员可能会丢失信息),因此您无法获取其地址(同样地,您无法取得地址)一元减去)

你需要一些像

这样的中间步骤
  #define TTe0 (*((u8*)Te+0))

然后你可以写&TTe0

如果您有许多类似于#define Te0的宏定义,您可以编写一些脚本(可能使用sedawk)来生成包含此类#define TTe0的标头,然后包括适当的。

请记住,可以生成C代码(所以头文件)!然后,您可以为此目的调整构建过程(例如,编辑一些Makefile)。

详细了解C preprocessor,特别是documentation。您可以使用gcc -C -E

获取(然后研究)预处理的表单

(关于你的其他问题,请阅读一本好的C编程书,然后阅读C11标准即n1570;一旦预处理确实发生,表达式来自某些宏扩展的事实就无关紧要了,编译器主要看到预处理的形式)

你的问题有一个误导性的标题:这不是通过一个宏来获取地址,而是取一些演员的地址,这显然毫无意义。

您可以通过宏获取地址。一个典型的例子是&errno,因为errno(3)是一个宏(在内部头文件/usr/include/bits/errno.h中定义,它通过<errno.h>标准头包含在内。