我有一个变量,其地址作为第四个参数传递到setsocketopt。请注意,此参数被声明为常量指针(const void *optval
)。
在修补程序中,我将其声明更改为静态constexpr,以供审核。对此更改的审阅者担心:他觉得是否可以始终使用constexpr的地址存在疑问。他建议我将其设为const。谷歌搜索之后,我找不到关于constexpr变量的地址以及对此的担忧。有人可以解释一下有关constexpr变量地址的保证以及对使用它的注意事项(如果有的话)吗?
如果有帮助,请看下面的代码(我添加了static constexpr
,之前只是int
)
static constexpr int ONE = 1;
setsockopt(socket_fd, IPPROTO_TCP, TCP_NODELAY, &ONE, sizeof(ONE));
谢谢!
答案 0 :(得分:4)
每个对象都保证每个[intro.object]/8都有一个地址
对象的大小为非零
不是潜在重叠的子对象,或者
不是类类型,或者
是具有虚拟成员函数或虚拟基类的类类型,或者
具有大小不为零的子对象或长度为非零的位域。
否则,如果对象是标准布局类类型的基类子对象,并且没有非静态数据成员,则其大小为零。否则,对象定义为零的情况由实现定义。 除非是位字段,否则大小不为零的对象应占用一个或多个字节的存储空间,包括其任何子对象全部或部分占用的每个字节。普通可复制或标准布局类型([basic.types])的对象应占据连续的存储字节。
强调我的
由于ONE
是非类非位字段类型,因此它在存储中,您可以获取其地址。
答案 1 :(得分:4)
是的,您可以使用不是非类型非引用模板参数或位字段的任何对象的地址。声明为constexpr
的变量(或隐式为常量表达式的变量)可以在更多上下文中使用,而不是更少。
确实,编译器通常可以避免为constexpr
变量使用任何内存存储,如果不需要的话。。但是,如果采用该地址,则可能需要存储内存,因此在这种情况下,编译器将需要将其更像是普通对象。