能否存在一个占用0字节的c++类型?
Can there be a C++ type that takes 0 bytes
我试图声明一个占用零字节的c++变量。它在一个联合中,我开始的类型是int[0]。我不知道这是否真的是零字节(尽管sizeof(int[0])是0)。我需要一个更好的方法来声明一个0字节类型,希望可以被类型定义为像nullType或emptyType这样的东西。变量是在一个联合中,所以在最后内存是保留的。我尝试了void,希望它能工作,但是c++抱怨了。我使用的是Ubuntu 10.10,带有当前版本的内核和最新的GCC。这里是联合:
union RandomArgumentTypesFirst
{
uint uintVal;
nullType nullVal;
}
这里是typepedef:
typedef int[0] nullType;
编译器对typedef这样说:
error: variable or field ‘nullVal’ declared voidmake[2]:
当我输入int[0]
时,它工作了。有什么建议吗?
编辑:正如@fefe在评论中所说,int[0]
可能由编译器作为扩展提供。GCC的网站说编译器默认有很多扩展。
typepedef拼写错误:
typedef int nullType[0];
正如其他人指出的,你不能有一个大小为0的对象;然而,编译器可以(并且经常)提供 Empty Base Class
优化。
- http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Empty_Base_Optimization
- http://www.cantrip.org/emptyopt.html("空成员"优化)
在c++中不能实例化任何占用零字节的数据类型。标准规定了一个空类,例如:
class Empty {};
…将导致以下为真:
Empty emp;
assert( sizeof(emp) != 0 );
这样做的原因是您可以获取对象的地址。
编辑:我最初说sizeof
将是1
,但根据@ al的评论,我在标准中找到了相关的段落,它确实只是非零:
(类)§9/3
类类型的完整对象和成员子对象必须具有非零大小
标准明确禁止存在大小为0的类型实例,原因是如果一个对象的大小可以为0,那么两个不同的对象可以位于完全相同的地址。例如,一个空结构体,即使用作不同类型的基,编译器也可以让它的size == 0,它也必须具有size> 0的值以符合这一要求。
你想用空类做什么?
c++中的变量永远不能为零字节。每个对象必须有唯一的地址,如果大小为0,这是不可能的。
顺便说一下,int[0]
在标准c++中是非法的。如果您使用的是GCC,使用-pedantic
选项编译它,您将得到以下警告:
warning: ISO C++ forbids zero-size array 'x' [-pedantic]
同样,typedef
的语法应该是这样的:
typedef int array[100]; //zero cannot be size - illegal!
c++标准明确要求每个类型的size至少为1。这与每个对象都有唯一地址的要求密切相关(如果Foo
的大小为0,则考虑Foo x[10]
)。
听起来你想要std::optional.
它不会有sizeof
0,但这对于表达空值并不重要。
在一个相关的注意,有一个c++提案(P0146R1)使void
成为一个常规类型。
论文继续讨论了为什么sizeof(void)
不能为0。
为什么sizeof(void)不等于0?
一个反复出现的建议是设置sizeof(void)报告0并允许多个实例共享相同的地址。这将防止用户不得不使用类似于空的技巧基础优化,以便更优化地使用内存。理想情况下,这将是这种情况,但这种语言的变化既庞大又超出了提案的范围。允许类型具有的大小为0,并且允许不同的实例共享一个地址,这意味着对现有代码进行剧烈而微妙的破坏性更改。例如,如果你要创建这样一个void类型的数组,一个指针,至少在传统意义上的,将不再能够作为一种迭代器放入该数组(特别意味着泛型代码依赖于这种0大小的类型现在会失败)。同样,任何依赖于对象的类型和地址作为惟一的代码将会失败对于void类型,即使它在其他方面完全可以接受。最后,如果void允许这样的大小,那么它确实应该允许允许用于任何类型,包括用户定义的类型。吃特价菜无效规则会让你多考虑一件事对void类型的处理方式不同。相反,这个提案选择了不指定void的大小,因此由existing控制语言规则。在实践中,预计可能会出现空白在大多数实现中大小为1,尽管这不是必需的。如果一个最终对语言进行了修改,允许大小为0的类型,那么void就可以隐式地利用这一点。
虽然这个问题是针对c++的,但应该注意的是,C中的空结构可能导致sizeof
为0。然而,这是未定义的行为。
如果struct-declaration-list不包含命名成员,则是未定义的。
- 从不同线程使用int64的不同字节安全吗
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 在UNIX系统中使用DIR查找文件的字节大小
- 如何使用Crypto++并为RSA返回可打印的字节/字符数组
- std::当在256字节边界上写入整数时,流的奇怪行为
- 当比特(而不是字节)的顺序至关重要时的持久性
- 从文件中读取多个字节,并将它们存储在C++中进行比较
- 如何在文件中查找字节序列
- luaL_dofile在已知良好的字节码上失败,可以使用未编译的版本
- 字节到位运算符重载C++
- 在java中读取c++字节的位字段
- 使用 std::vector::reverse_iterator 将 int 序列化为字节向量?
- 字节真的是最小可寻址单元吗
- struct.error:解压缩 C++ 结构时,解包需要 288 字节的缓冲区
- 读取文件中所有可能的十六进制 16 字节序列并打印每个序列
- 如何使用 OpenCV 解码在两个 UWP 应用之间发送的图像字节?
- 如何将字节数组元素替换为修改的十六进制 ASCII 符号?
- asn1c 不会从 asn.1 模块中提取八位字节字符串的默认值
- 如何将原始字节附加到 std::vector?
- 基于字节数组生成静态范围整数值