static_assert和offsetof

背景: muduo网络库中的如下用法:

1 static_assert(sizeof(InetAddress) == sizeof(struct sockaddr_in6),
2               "InetAddress is same size as sockaddr_in6");
3 static_assert(offsetof(sockaddr_in, sin_family) == 0, "sin_family offset 0");
4 static_assert(offsetof(sockaddr_in6, sin6_family) == 0, "sin6_family offset 0");
5 static_assert(offsetof(sockaddr_in, sin_port) == 2, "sin_port offset 2");
6 static_assert(offsetof(sockaddr_in6, sin6_port) == 2, "sin6_port offset 2");

里面用到的 static_assert 和 offsetof 不知道是个什么东西。

引用: https://blog.csdn.net/drdairen/article/details/76689014

assert的作用是先计算表达式 expression ,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。assert分为动态断言和静态断言2种。

c++0x引入了static_assert关键字,用来实现编译期间的断言,叫静态断言。
语法:static_assert(常量表达式,要提示的字符串);
如果第一个参数常量表达式的值为false,会产生一条编译错误,错误位置就是该static_assert语句所在行,第二个参数就是错误提示字符串。
然后通过调用 abort 来终止程序运行。

使用static_assert,我们可以在编译期间发现更多的错误,用编译器来强制保证一些契约,并帮助我们改善编译信息的可读性,尤其是用于模板的时候。
static_assert可以用在全局作用域中,命名空间中,类作用域中,函数作用域中,几乎可以不受限制的使用。

编译器在遇到一个static_assert语句时,通常立刻将其第一个参数作为常量表达式进行演算,但如果该常量表达式依赖于某些模板参数,则延迟到模板实例化时再进行演算,这就让检查模板参数成为了可能。

性能方面,由于是static_assert编译期间断言,不生成目标代码,因此static_assert不会造成任何运行期性能损失。

简单例子:

static_assert(sizeof(void *)==4,"64位系统上不支持!");
  • 1

该static_assert用来确保编译仅在32位的平台上进行,不支持64位的平台,该语句可以放在文件的开头处,这样可以尽早检查,以节省失败情况下的编译时间。

 

offsetof 

C语言offsetof()宏,是定义在stddef.h。用于求出一个structunion数据类型的给定成员的size_t类型的字节偏移值。offsetof()宏有两个参数,分别是结构名与结构内的成员名。不能声明为C原型。[1]

例如下面的结构体:

1 struct MyStruct
2 {
3        char c;
4        int   b; 
5 };

其中:

offsetof(MyStruct, c) == 0;

offsetof(MyStruct, b)==4;

假设结构体的开始位置为0 ,求对应成员的偏移。

 

posted @ 2020-10-09 15:33  熊鑫xxx1x  阅读(308)  评论(0)    收藏  举报