Reputation: 303397
In writing some code to print backtraces in C++, I came across this answer, which includes copying the definition of a type:
/* This structure mirrors the one found in /usr/include/asm/ucontext.h */
typedef struct _sig_ucontext {
unsigned long uc_flags;
struct ucontext *uc_link;
stack_t uc_stack;
struct sigcontext uc_mcontext;
sigset_t uc_sigmask;
} sig_ucontext_t;
I can't just include <asm/ucontext.h>
since there it is defined as simply ucontext
which collides with a similarly named type from <sys/ucontext.h>
(which is included from the necessary <signal.h>
):
/* Userlevel context. */
typedef struct ucontext
{
unsigned long int uc_flags;
struct ucontext *uc_link;
stack_t uc_stack;
mcontext_t uc_mcontext;
__sigset_t uc_sigmask;
struct _libc_fpstate __fpregs_mem;
} ucontext_t;
All I need here is the struct sigcontext uc_mcontext
member from the asm
version. Is there a better way to retrieve that value than just copying out this struct? That seems incredibly hackish and error-prone to me.
Upvotes: 3
Views: 1494
Reputation: 21955
One potential workaround is to make asm/ucontext.h
the first include in your source file and abuse preprocessor to rename conflicting definition:
#define ucontext asm_ucontext
#include <asm/ucontext.h>
#undef asm_ucontext
You can then use asm_ucontext
to refer to alternative definition of ucontext
.
A bit less hacky approach is to employ sed to automatically extract necessary definitions from system file:
$ echo '#include <asm/ucontext.h>' | gcc -x c - -E -o- | sed -n '/^struct ucontext/,/^};/{ s/ucontext/asm_ucontext/; p}' | tee asm_ucontext.h
struct asm_ucontext {
unsigned long uc_flags;
struct asm_ucontext *uc_link;
stack_t uc_stack;
struct sigcontext uc_mcontext;
sigset_t uc_sigmask;
};
Upvotes: 1