【发布时间】:2017-03-11 13:02:47
【问题描述】:
我正在创建一个库,我想隐藏和保护(使不可写)结构类型(只能使用库函数进行编辑)。 我正在使用:
typedef _STRINGLIB_STRING_CONST_ struct
{
#if defined(_STRINGLIB_OVERLOADING_WAIT_) || defined(_STRINGLIB_STRING_ACCESSIBLE_)
//actual string
char *getString;
//string size in bytes
size_t getSize;
//string size in characters (=size in bytes-1)
size_t getSizeChars;
//should both point to _STRINGLIB_ALLOCATION_TRUE_ when string is allocated
void *stringAllocation;
void *stringSignature;
#else
struct
{
size_t _block_a;
void *_block_b;
void *_block_c;
void *_block_d;
size_t _block_e;
}_block;
#endif // _STRINGLIB_OVERLOADING_WAIT_
}String;
其中_STRINGLIB_STRING_CONST_ 始终为常量,除非从源文件调用头文件或用户在包含库之前声明了_STRINGLIB_STRING_ACCESSIBLE_; _STRINGLIB_OVERLOADING_WAIT_ 由源文件声明(之后未声明)。
看起来它工作正常(我使用的是 GCC 4.9.2),但我想确定这是否总是正常或未定义的行为。
.
.
附加信息:忘了提到我在 stringlib.h 文件的顶部有这些定义:
#ifdef _STRINGLIB_OVERLOADING_WAIT_
#undef _STRINGLIB_STRING_CONST_
#define _STRINGLIB_STRING_CONST_
#elif !defined(_STRINGLIB_STRING_ACCESSIBLE_)
#undef _STRINGLIB_STRING_CONST_
#define _STRINGLIB_STRING_CONST_ const
#else
#undef _STRINGLIB_STRING_CONST_
#define _STRINGLIB_STRING_CONST_
#endif // _STRINGLIB_OVERLOADING_WAIT_
#ifndef _STRINGLIB_H_
#define _STRINGLIB_H_
//<...>
【问题讨论】:
-
结构对齐可能会有所不同,因为您没有以相同的方式对结构字段进行排序,因此结构的大小可能会被视为不同,这很糟糕。
-
你想要的是一个“不透明的结构”。有关如何做到这一点的一些想法,请参阅stackoverflow.com/questions/3965279/…。
-
请注意,您应该谨慎使用以下划线和大写字母开头的名称。它们被无条件地保留给实现,随心所欲——你的代码可能会中断,除非它是实现的一部分。如果它坏了,你就没有任何人可以卷土重来。您无法安全/可靠地将代码移植到您不参与实施的任何地方。一般避免前导下划线。有很多问题都详细说明了(例如What does double underscore (
__const) mean in C)。 -
@JonathanLeffler:我希望 C 标准的作者保留一种标识符,将某些名称的所有权分配给各种实现的创建者;名称可能不是“迷人的”,但是想要在他的 C 编译器上支持新功能的人得到所有以 STDCX493167 开头的名称,并添加了一个内在的例如将左值设置为未指定的值,人们可以编写代码,在存在时使用该内在函数,同时仍与不存在它的编译器兼容。
标签: c struct constants private undefined-behavior