简体   繁体   中英

error “cannot appear in a constant-expression” in g++ but not in gcc

 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");

Above code(part of main code) is successfully compiled in GCC compiler. But while compiling through G++, it is giving fillowing error: error: 'dr_index' cannot appear in a constant-expression in line 103. set_hw_br is called from another function.

Any idea why this failing in g++?

Thanks.

The offsetof macro requires that the member-designator has to produce an address constant (C11 7.19/3):

 offsetof(type, member-designator) 

which expands to an integer constant expression that has type size_t , the value of which is the offset in bytes, to the structure member (designated by member-designator ), from the beginning of its structure (designated by type ). The type and member designator shall be such that given

 static type t; 

then the expression &(t. member-designator ) evaluates to an address constant. (If the specified member is a bit-field, the behavior is undefined.)

In your code, t.u_subreg[dr_index] is not a constant, because dr_index is not a constant.

GCC implements offsetof with a compiler intrinsic so what is allowed in an offsetof expression depends on the rules of GCC's intrinsic. As an extension to the standard, the GCC C front-end allows a non-constant expression as input and produces a non-constant result. The C++ front-end does not allow it, giving the error telling you dr_index cannot be used there.

You can change the offsetof expression to only use constants:

offsetof(struct user, u_debugreg[0])

then you can add the index to it, where T is the type in the array u_debugreg :

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

(This assumes that u_debugreg is an actual array, not a pointer).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM