thi*_*his 1 c struct pointers const c99
我有一个结构定义,只在声明它的.c文件中可见.
struct private
{
int n ;
void* data ;
int field ;
}
Run Code Online (Sandbox Code Playgroud)
访问成员的唯一方法是在同一文件中定义并在标头中声明的函数.
我声明了一个在任何地方都可见的标题中的结构
struct public
{
int n ;
void* data ;
}
Run Code Online (Sandbox Code Playgroud)
然后我有一个函数返回实际上私有结构化的公共结构
struct public* this = GetPrivateStruct() ; //function returns pointer to struct private malloced internally, casted to public struct
this->n = 123 ;
Run Code Online (Sandbox Code Playgroud)
到目前为止,代码是正确的,没有未定义的行为.
但是,我可以使用const成员来创建公共结构吗?
struct public
{
const int n ;
const void* data ;
}
Run Code Online (Sandbox Code Playgroud)
所以只允许阅读:
void* private_struct = GetPrivateStruct() ;
struct public* this = ( struct public* )private_struct ;
this->n = 123 ; //<-- this will now give an error which is fine as it is not allowed
int n = this->n ; //we can only read the value
Run Code Online (Sandbox Code Playgroud)
int并且const int不兼容类型(6.7.3p10)因此您将无法应用公共初始序列规则(6.5.2.3p6)进行存储union; 也就是说,这不是你正在做的事情,所以你必须依赖左值转换规则(6.3.2.1p2),它允许剥离一层类型限定,但前提是左值引用适当类型的对象.
请注意,从6.2.5p26和6.7.2.1p15我们可以推断出两个structs具有相同的布局(对于公共元素),但它并不遵循您所做的是合法的.正如在C中使用const的"私有"结构成员所讨论的那样,关键是优化器(当对用户代码进行操作时)将注意到成员struct public是const并且推断它们不能在任何地方改变,包括实现的(成员)函数.
但是,如果您很乐意相信用户不进行常量转换this->n,那么可以信任它们不进行常量转换this,那么为什么不给它们一个指向const合格对象的指针呢?你甚至可以制作public一个consttypedef:
typedef const struct initial {
int n;
void *data;
} public;
Run Code Online (Sandbox Code Playgroud)
此外,initial以一些额外字符为代价重用布局是有意义的:
struct private {
struct initial i;
int field;
};
Run Code Online (Sandbox Code Playgroud)
现在,您可以给用户&this->i和initial和public是兼容的类型,你甚至不需要投什么的合格版本(尽管你可以通过6.7.2.1p15).