错误"不能出现在常量表达式中#34;用g ++而不是gcc

时间:2014-03-25 10:01:14

标签: c++ linux gcc g++

 98 static inline int set_hw_br(pid_t tracee, dr7_t *pdr7, void *addr, int dr_index)
 99 {
100     errno = 0;
101     printf("LINE = %d <pid> %d, dr_index= %d addr=%u \n",__LINE__, tracee, dr_index, addr);
102     //if (ptrace(PTRACE_POKEUSER, tracee, offsetof(struct user, u_debugreg[dr_index]), addr))
103     if (ptrace(PTRACE_POKEUSER, tracee, offsetof(struct user, u_debugreg[dr_index]), addr))
104     {
105         int ii = errno;
106         printf("MKH: 22  errno = %d\n", ii);
107         ptrace(PTRACE_DETACH, tracee, 0, 0);
108         return -1;
109     }
110     else
111         printf("PTRACE_POKEUSER passed...\n");

上面的代码(主代码的一部分)在GCC编译器中成功编译。但是在通过G ++进行编译时,它会在第103行给出填充错误:error: 'dr_index' cannot appear in a constant-expression。从另一个函数调用set_hw_br。

知道为什么g ++失败了吗?

感谢。

1 个答案:

答案 0 :(得分:5)

offsetof宏要求 member-designator 必须产生地址常量(C11 7.19 / 3):

offsetof(type, member-designator)
     

扩展为类型为size_t的整数常量表达式,其值为   这是结构成员的偏移量(以字节为单位)(由 member-designator 指定),   从其结构的开头(由 type 指定)。类型和成员指示符   应该是给定的

static type t;
     

然后表达式&(t. member-designator )计算为地址常量。 (如果   指定的成员是位字段,行为未定义。)

在您的代码中,t.u_subreg[dr_index]不是常量,因为dr_index不是常量。

GCC使用compiler intrinsic实现offsetof,因此offsetof表达式中允许的内容取决于GCC内在规则。作为标准的扩展,GCC C前端允许非常量表达式作为输入并产生非常量结果。 C ++前端不允许它,给出错误告诉你dr_index不能在那里使用。

您可以将offsetof表达式更改为仅使用常量:

offsetof(struct user, u_debugreg[0])

然后你可以添加索引,其中T是数组u_debugreg中的类型:

offsetof(struct user, u_debugreg[0]) + sizeof(T)*dr_index

(这假设u_debugreg是实际数组,而不是指针。)