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 ++失败了吗?
感谢。
答案 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
是实际数组,而不是指针。)