[C/C++标准库]_[初级]_[计算结构体成员的偏移量]

时间:2021-07-20 16:05:00


场景:

1. C结构体里计算结构体的偏移量平常看来没什么必要,但是放到插件结构的设计里就有必要了,比如只能使用偏移量访问的场景,而不能使用引用成员变量的场景。

2. 在设计一致性的接口时,公用的接口不怎么变化的,但是插件模块的结构可以不需要根据统一结构来设计,他们只需要提供偏移量给公用接口调用就行了,不同的插件

可能偏移量不一致,因为他们可以独立实现。公用接口就可以通过偏移量来访问不同的变量。

3. 可以使用stddef.h文件里的  offsetof


/* Define offsetof macro */#ifdef __cplusplus

#ifdef _WIN64
#define offsetof(s,m) (size_t)( (ptrdiff_t)&reinterpret_cast<const volatile char&>((((s *)0)->m)) )
#else
#define offsetof(s,m) (size_t)&reinterpret_cast<const volatile char&>((((s *)0)->m))
#endif

#else

#ifdef _WIN64
#define offsetof(s,m) (size_t)( (ptrdiff_t)&(((s *)0)->m) )
#else
#define offsetof(s,m) (size_t)&(((s *)0)->m)
#endif



ffmpeg部分代码:

注意这里的OFFSET

static const AVOption options[]={{"b", "set bitrate (in bits/s)", OFFSET(bit_rate), FF_OPT_TYPE_INT, AV_CODEC_DEFAULT_BITRATE, INT_MIN, INT_MAX, V|E},{"ab", "set bitrate (in bits/s)", OFFSET(bit_rate), FF_OPT_TYPE_INT, 64*1000, INT_MIN, INT_MAX, A|E},{"bt", "set video bitrate tolerance (in bits/s)", OFFSET(bit_rate_tolerance), FF_OPT_TYPE_INT, AV_CODEC_DEFAULT_BITRATE*20, 1, INT_MAX, V|E},{"flags", NULL, OFFSET(flags), FF_OPT_TYPE_FLAGS, DEFAULT, 0, UINT_MAX, V|A|E|D, "flags"},{"mv4", "use four motion vector by macroblock (mpeg4)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_4MV, INT_MIN, INT_MAX, V|E, "flags"},{"obmc", "use overlapped block motion compensation (h263+)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_OBMC, INT_MIN, INT_MAX, V|E, "flags"},{"qpel", "use 1/4 pel motion compensation", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_QPEL, INT_MIN, INT_MAX, V|E, "flags"},{"loop", "use loop filter", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_LOOP_FILTER, INT_MIN, INT_MAX, V|E, "flags"},{"qscale", "use fixed qscale", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_QSCALE, INT_MIN, INT_MAX, 0, "flags"},{"gmc", "use gmc", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_GMC, INT_MIN, INT_MAX, V|E, "flags"},{"mv0", "always try a mb with mv=<0,0>", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_MV0, INT_MIN, INT_MAX, V|E, "flags"},{"part", "use data partitioning", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_PART, INT_MIN, INT_MAX, V|E, "flags"},{"input_preserved", NULL, 0, FF_OPT_TYPE_CONST, CODEC_FLAG_INPUT_PRESERVED, INT_MIN, INT_MAX, 0, "flags"},

测试代码,使用vs2010编译:

void TestOffset(){	//1.编译器会对结构体内数据类型自动对其类型大小值的倍数对齐.	struct t	{		char c;		char b;		int e;		int e1;		double d;	};	cout << offsetof(t,b) << endl;	cout << offsetof(t,e) << endl;	cout << offsetof(t,e1) << endl;	cout << offsetof(t,d) << endl;}int _tmain(int argc, _TCHAR* argv[]){	TestOffset();	return 0;}

输出:

14816