Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
779 views
in Technique[技术] by (71.8m points)

c - Is there a way to determine a member offset at compile time?

I'm finding I'm spending a lot of time trying to determine member offsets of structures while debugging. I was wondering if there was a quick way to determine the offset of a member within a large structure at compile time. (Note: I know several ways of creating compile time assertions that an offset is in a given range, and I can do a binary search for the correct value, but I'm looking for something more efficient). I'm using a fairly recent version of gcc to compile C code.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

offsetof is what you want for this and it compile time. The C99 draft standard section 7.17 Common definitions paragraph 3 says:

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 [...]

the man pages linked above has the following sample code, which demonstrates it's usage:

struct s {
    int i;
    char c;
    double d;
    char a[];
};

/* Output is compiler dependent */

printf("offsets: i=%ld; c=%ld; d=%ld a=%ld
",
        (long) offsetof(struct s, i),
        (long) offsetof(struct s, c),
        (long) offsetof(struct s, d),
        (long) offsetof(struct s, a));
printf("sizeof(struct s)=%ld
", (long) sizeof(struct s));

sample output, which may vary:

 offsets: i=0; c=4; d=8 a=16
 sizeof(struct s)=16

For reference constant expressions are covered in section 6.6 Constant expressions and paragraph 2 says:

A constant expression can be evaluated during translation rather than runtime, and accordingly may be used in any place that a constant may be.

Update

After clarification from the OP I came up with a new methods using -O0 -fverbose-asm -S and grep, code is as follows:

#include <stddef.h>

struct s {
        int i;
        char c;
        double d;
        char a[];
    };

int main()
{
    int offsetArray[4] = { offsetof(struct s, i ), offsetof( struct s, c ), offsetof(struct s, d ), offsetof(struct s, a )  } ;

    return 0 ;
}

build using:

gcc -x c -std=c99 -O0 -fverbose-asm  -S main.cpp && cat main.s | grep offsetArray

sample output (live example):

movl    $0, -16(%rbp)   #, offsetArray
movl    $4, -12(%rbp)   #, offsetArray
movl    $8, -8(%rbp)    #, offsetArray
movl    $16, -4(%rbp)   #, offsetArray

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...