C++14 是否定义了 unsigned int 填充位上按位运算符的行为?

2024-04-17

C++标准

If a C++14 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf实现包括在底层字节中填充位unsigned int,标准是否指定是否不得对填充位执行按位运算?

此外,C++14 标准是否指定是否相等和关系 运算符必须忽略填充位?

指南

如果在这方面缺乏规范,是否有某种形式 对这些运算符对填充位的预期行为达成共识吗?

我在 Stack Overflow 上发现了相互矛盾的答案。轨道上的轻盈竞赛 https://stackoverflow.com/questions/29394518/whats-the-result-of-a-b/29394559#29394559 and ecatmur https://stackoverflow.com/questions/29394518/whats-the-result-of-a-b/29394674#29394674说按位运算符不适合算术,因为它们应用于所有位(包括填充位),而克里斯托夫 https://stackoverflow.com/questions/4475540/c-question-padding-bits-in-unsigned-integers-and-bitwise-operations-c89/4475689#4475689 and 巴泰克·巴纳切维奇 https://stackoverflow.com/questions/29394518/whats-the-result-of-a-b/29394720#29394720假设按位运算符处理整数的逻辑值并忽略填充。

参考

相关答案:关于填充位的存在 (1 https://stackoverflow.com/questions/42297434/does-uint-max-have-all-bits-set-to-1/42297684#42297684, 2 https://stackoverflow.com/questions/3949457/can-an-integer-be-nan-in-c/3949459#3949459, 3 https://stackoverflow.com/questions/12125650/what-do-the-c-and-c-standards-say-about-bit-level-integer-representation-and-m/12125881#12125881), 关于缺乏明确的 C++ 规范 (4 https://stackoverflow.com/questions/29394518/whats-the-result-of-a-b).

填充位的定义C++14 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf- § 3.9.1 - 基本类型:

对于窄字符类型,对象表示的所有位都参与值表示。对于无符号窄字符类型,值表示的所有可能的位模式都表示数字。这些要求不适用于其他类型。

C++14 中对象表示和值表示的定义 - § 3.9 - 类型:

The object representation of an object of type T is the sequence of N unsigned char objects taken up by the object of type T, where N equals sizeof(T). The value representation of an object is the set of bits that hold the value of type T. For trivially copyable types, the value representation is a set of bits in the object representation that determines a value, which is one discrete element of an implementation-defined set of values.44

脚注 44) 目的是 C++ 的内存模型与 ISO/IEC 9899 编程语言 C 的内存模型兼容。

C++14 中按位 AND 的定义 - § 5.11 - 按位 AND 运算符:

执行通常的算术转换;结果是操作数的按位 AND 函数。该运算符仅适用于整数或无范围枚举操作数。

C++14 中加法的定义 - § 5.7 - 加法运算符:

通常的算术转换是针对算术或枚举类型的操作数执行的。另外,[...]两个操作数都应具有算术或无范围枚举类型[...]。二进制的结果+运算符是操作数之和。


首先,C++ 标准本身几乎没有提及填充位。基本上所有关于填充位的讨论都来自基础文档(即 C 标准)。

所以真正的问题是 C 标准对事物的规定。它的脚注 54 给出了一般填充位的相当简洁的总结:

填充位的某些组合可能会生成陷阱表示,例如,如果一个填充位是奇偶校验位。无论如何,对有效值的任何算术运算都不能生成陷阱表示,除非作为异常条件(例如溢出)的一部分。填充位的所有其他组合都是值位指定的值的替代对象表示。

运营商可能会改变一个大的填充。最明显的情况是代表奇偶校验的填充位。如果更改值的奇偶校验,奇偶校验位也会更改以匹配。

“值的替代对象表示”部分基本上意味着只要您保持在“范围内”,填充位就不会影响您的结果。例如,如果比较两个值,则仅使用表示位来确定结果 (6.2.6.1/4):

具有相同对象表示的两个值(NaN 除外)比较相等,但比较相等的值可能具有不同的对象表示。

您必须小心的时间和地点大多涉及未定义或实现定义的行为。例如,如果您将一个值存储到联合中的一个值中,然后在联合中检索不同的值,则第二个值可能会将填充位设置为陷阱表示,因此即使以这种方式查看该值也可能会导致您的崩溃程序(或其他)。

同样,如果你要取两个值,memcpy每个字节都与 unsigned char 缓冲区相比,这些字节的某些位可能比较不相等,即使它们表示的值比较相等。

即使您从未使用过,这个地方也可能会咬您mempy直接与一些比较和交换运算符一起使用。这些使用memcpy and memcmp对于底层操作,因此即使所表示的值相等,它们也可能会比较不相等:

[原子.类型.操作]/23:

如果基础类型具有填充位、陷阱位或同一值的替代表示,则比较和交换操作的 memcpy 和 memcmp 语义可能会导致与运算符==比较相等的值的比较失败。因此,compare_exchange_strong 使用时应格外小心。另一方面,compare_exchange_weak 应该快速收敛。

旁注:两个大引号是描述性的,而不是规范性的——从规范的角度来看,填充位几乎没有任何意义;几乎任何可能暴露填充位或其值的东西都涉及实现定义或未定义的行为。这里唯一的规范性引用基本上是这样说的:“填充位没有效果。”

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++14 是否定义了 unsigned int 填充位上按位运算符的行为? 的相关文章

  • 基于我的 C# 类生成 xml 文件

    我有 xml 文件 每次都需要根据新客户的要求进行更新 大多数时候 xml 不正确是因为手动更新了 xml 文件 我正在考虑编写一个提供适当验证的程序 网络 Windows 并根据 ui 的输入 我将创建 xml 文件 下面是我的示例 xm
  • 在QT中以不同的时间间隔更新GUI [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想知道如何在QT中以不同的时间间隔更新GUI 最好的是我可以控制时间间隔 我知道 QTimer 可以在同一时间间隔更新 GUI 但我
  • iTextSharp 居中对齐文档对象内的对象

    是否有一种快速而简单的方法可以将文档对象中的对象居中对齐 Without执行任何计算逻辑 即 获取页面宽度 获取内容宽度 除以二等 我在 Document 对象内的 Paragraph 对象中有一个 PdfPTable 对象 我想将段落对象
  • 如何在 C 中的 for (;;) 循环中声明多个变量?

    我认为可以在一个变量中声明多个变量for loop for int i 0 char ptr bam i lt 10 i 但我刚刚发现这是不可能的 GCC 给出以下错误 错误 char 之前应有不合格的 id 你真的不能在一个变量中声明不同
  • 无法从 GetProcessId(.. hWnd) (pInvoke) 中提取 processID

    我使用以下方法 DllImport kernel32 dll SetLastError true static extern int GetProcessId IntPtr hWnd 尝试获取正在运行的进程的 processId 我拥有的唯
  • Qt5 CMake 将所有库包含到可执行文件中

    我正在尝试使用 Qt 5 14 构建一个发布模式下的应用程序 并且 Qt Creator 内部一切正常 但是当我尝试单独运行可执行文件时 我收到如下错误 OS Windows 10 Qt 5 14 Cmake 3 5 我尝试过的 设置 CM
  • gdb 通过指向错误的代码行显示不正确的回溯

    我们可以通过在源代码中包含多个中止调用 用非常简单的示例重现此问题 在下面的示例代码中 我们在不同条件下总共有四个中止调用 但是当我们使用优化标志 O3 进行编译时 我们只能看到一个中止调用的调试信息 因此 在这四个中止调用中发生崩溃时 g
  • 窗口的打开事件和窗口句柄

    如何从刚刚打开的 Outlook 窗口获取窗口句柄 IntPtr OutLook Items items oFolder Items foreach OutLook MailItem mail in items mail Display I
  • csharp类可以像java类一样“继承”xml文档吗?

    我正在向一些csharp代码添加注释 并且我正在使用 net 或其他东西 提供的xml语言 我有一个接口和一些实现类 我在界面中有一个方法 它有一个注释 在实现类中没有对实现方法进行注释 当人们在java中这样做时 javadoc在生成文档
  • CTAD 可以在模板类的成员内部使用吗?

    C 有一个有用的功能 即模板参数隐含在模板类内的代码中A 然而 对于建筑来说 这似乎与 CTAD 发生冲突 如何让 CTAD 优先 例如 这里有一个错误f会员因为A被解释为A
  • std::线程构造和执行

    我在 中找不到任何信息文档 http en cppreference com w cpp thread thread thread是否能保证线程对象构造完成后线程实际上正在运行 换句话说 是否可以保证线程构造函数完成后线程函数已经被执行 一
  • 使用枚举作为常量表达式。哪个编译器是正确的?

    以下代码使用枚举成员m作为常量表达式 即作为模板参数 该代码可以在 gcc 下编译 但不能在 clang 下编译 现场演示 http coliru stacked crooked com a 79f0d052864fec19 20live
  • 访问 ASP.NET 中 App_Code 中未声明的类

    我有时定义业务逻辑类来 帮助 我的 ASPX 代码隐藏类 对我来说 将它们都包含在代码隐藏文件中是最有意义的 因为它们一起工作 但是 我偶尔想从 App Code 中定义的更高级别的类访问业务逻辑类 但它们不能在文件外部自动访问 因此 问题
  • 开源 C# 套接字 (TCP + UDP) 库 [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我对 NET 框架的标准套接字类感到头疼 有人可以推荐一个高效的开源 C 套接字 TCP UDP 库来处理套接字消息吗 使用 Kerry Jia
  • HTTP 请求未经客户端身份验证方案“Ntlm”的授权 从服务器收到的身份验证标头为“NTLM”

    我知道有很多与此类似的问题 但我找不到针对这一特定问题的问题 首先有几点 I have 无控制通过我们的 Sharepoint 服务器 我无法调整任何 IIS 设置 我相信我们的IIS服务器版本是IIS 7 0 我们的 Sharepoint
  • 如何从 XBAP 关闭浏览器?

    我正在完全信任地使用 XBAP 应用程序 单击按钮时 我需要关闭托管 XBAP 的浏览器 我怎样才能实现这个目标 Application Currenty ShutDown 仅关闭应用程序 使浏览器保持空白 我知道这是一个非常老的问题 但如
  • 布局兼容类型的联合

    看这段代码 struct A short s int i struct B short s int i union U A a B b int fn U u u a i 1 return u b i 是否保证fn 回报1 注意 这是一个后续
  • OpenGL 和加载/读取 AoSoA(混合 SoA)格式的数据

    假设我有以下 AoSoA 格式的简化结构来表示顶点或点 struct VertexData float px 4 position x float py 4 position y 也就是说 每个实例VertexData存储4个顶点 我见过的
  • c 中的帕斯卡三角形与递归函数

    您好 这是我用于计算帕斯卡三角形的代码 但它运行错误 已停止工作 为什么 我认为它的错误在于 paskal 函数 include
  • 如何在 C 中将向量参数传递给 OpenCL 内核?

    我在将向量类型 uint8 参数从 C 中的主机代码传递到 OpenCL 内核函数时遇到问题 在主机中 我将数据存储在数组中 cl uint dataArr 8 1 2 3 4 5 6 7 8 我的真实数据不仅仅是 1 8 这只是为了便于解

随机推荐