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 ++编译时,会error: 'dr_index' cannot appear in a constant-expression
错误: error: 'dr_index' cannot appear in a constant-expression
在第103行error: 'dr_index' cannot appear in a constant-expression
中。set_hw_br从另一个函数中调用。
任何想法为什么这在g ++失败?
谢谢。
宏的offsetof
要求成员指定 offsetof
必须产生一个地址常量(C11 7.19 / 3):
offsetof(type, member-designator)
它从结构的开头(由type 指定 )扩展成一个整型常量表达式,该表达式的类型为
size_t
,其值是以字节为单位的结构成员(由member-designator指定)。 类型和成员代号应该是给定的static type t;
那么表达式
&(t.
-designator)
计算结果就是一个地址常量。 (如果指定的成员是位字段,则行为是未定义的。)
在你的代码中, t.u_subreg[dr_index]
不是一个常量,因为dr_index
不是一个常量。
GCC用一个编译器实现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
是一个实际的数组,而不是一个指针)。