热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

在gcc(C++11)中是(int32_t)255<<24未定义的行为吗?

如何解决《在gcc(C++11)中是(int32_t)255<<24未定义的行为吗?》经验,为你挑选了1个好方法。

在c ++ 11中,根据en.cppreference.com,

对于有符号和非负数a,如果它在返回类型中可表示,则<*2 b,否则行为未定义.

我的理解是,由于255*2 24不能表示为a int32_t,因此对(int32_t) 255 <<24 产量的评估是未定义的行为.那是对的吗?这可能是编译器依赖的吗?这是一个IP16环境,如果重要的话.

背景:这来自我与arduino.stackexchange.com上的用户的争论.根据他的说法,"根本就没有任何不确定":

你注意到大部分的位移是"实现定义".所以你不能从规范中引用章节和经文.您必须转到GCC文档,因为这是唯一可以告诉您实际情况的地方. gnu.org/software/gnu-c-manual/gnu-c-manual.html#Bit-Shifting - 对于负移位值,它只是"未定义".


编辑:从目前为止的答案来看,似乎我对C++ 11标准的阅读是正确的.然后我的问题的关键部分是这个表达式是否在gcc中调用未定义的行为.正如davmac在他的评论中所说,我问"GCC,一个实现,是否定义了一种行为,即使它未被语言标准定义".

从我链接到的gcc手册,看起来确实已经定义了,虽然我发现本手册的措辞听起来更像是教程而不是"语言法".从PSkocik的答案(以及Kane对该答案的评论)来看,它似乎是未定义的.所以我仍然有疑问.

我想我的梦想是在一些gcc文档中有明确的声明,说明1)gcc没有定义标准中明确未定义的任何行为,或者2)gcc确实从版本XX.XX定义了这种行为并且提交到保持在所有后续版本中定义.

编辑2:PSkocik删除了他的答案,我发现这很不幸,因为它提供了有趣的信息.根据他的回答,凯恩对答案的评论以及我自己的实验:

    (int32_t)255<<24 使用clang和编译时产生运行时错误 -fsanitize=undefined

    相同的代码即使使用g ++也不会产生错误 -fsanitize=undefined

    (int32_t)256<<24 编译时会出现运行时错误 g++ -std=c++11 -fsanitize=undefined

第2点与C++ 11模式中gcc比标准更广泛地定义左移的解释是一致的.根据第3点,这个定义可能只是C++ 14的定义.但是,第3点 与引用的手册是gcc(C++ 11模式)的完整定义的想法不一致,因为该手册没有提供可能未定义的提示.<<(int32_t)256<<24



1> Barry..:

随着时间的推移,这种情况发生了变化,并且有充分的理由,让我们来看看历史.请注意,在所有情况下,只需执行static_cast(255u <<24)一直定义的行为.也许只是这样做并侧面解决所有问题.


最初的C++ 11措辞是:

E1 <E1左移位E2位置; 空位是零填充的.如果E1具有无符号类型,则结果的值将比结果类型中可表示的最大值模数减1.否则,如果有一个有符号类型和非负值,并且在结果类型中可表示,那么这就是结果值; 否则,行为未定义.E1×2E2E1E1×2E2

255 <<24 是C++ 11中未定义的行为,因为结果值不能表示为32位有符号整数,它太大了.

这种未定义的行为会导致一些问题,因为constexpr 必须诊断未定义的行为 - 因此设置值的一些常用方法会导致硬错误.因此CWG 1457:

8.8 [expr.shift]第2段的当前措辞使得通过将(带符号)1左移到符号位来创建给定类型的最负整数的未定义行为,即使这并非罕见地完成并且有效正确地在大多数(二进制补码)架构上[...]因此,这种技术不能用于常量表达式,这将破坏大量代码.

这是针对C++ 11的缺陷.从技术上讲,符合标准的C++ 11编译器会实现所有缺陷报告,因此在C++ 11中说这不是未定义的行为是正确的.255 <<24C++ 11中的行为被定义为-16777216.

可以在C++ 14中看到缺陷后的措辞:

E1 <E1左移位E2位置; 空位是零填充的.如果E1具有无符号类型,则结果的值将比结果类型中可表示的最大值模数减1.否则,如果具有有符号类型和非负值,并且结果类型的相应无符号类型中可表示,则转换为结果类型的该值是结果值; 否则,行为未定义.E1×2E2E1E1×2E2

C++ 17中的措辞/行为没有变化.

但对于C++ 20,由于Signed Integers是Two's Complement(及其措辞文件),措辞大大简化:

E1 <是与模数一致的唯一值,其中是结果类型的范围指数.E1×2E22NN

255 <<24 仍然在C++ 20中定义了行为(具有相同的结果值),只是我们如何到达那里的规范变得更加简单,因为语言不必解决签名整数的表示形式的问题.实现定义.


推荐阅读
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • 如何搭建Java开发环境并开发WinCE项目
    本文介绍了如何搭建Java开发环境并开发WinCE项目,包括搭建开发环境的步骤和获取SDK的几种方式。同时还解答了一些关于WinCE开发的常见问题。通过阅读本文,您将了解如何使用Java进行嵌入式开发,并能够顺利开发WinCE应用程序。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 配置IPv4静态路由实现企业网内不同网段用户互访
    本文介绍了通过配置IPv4静态路由实现企业网内不同网段用户互访的方法。首先需要配置接口的链路层协议参数和IP地址,使相邻节点网络层可达。然后按照静态路由组网图的操作步骤,配置静态路由。这样任意两台主机之间都能够互通。 ... [详细]
  • This article discusses the efficiency of using char str[] and char *str and whether there is any reason to prefer one over the other. It explains the difference between the two and provides an example to illustrate their usage. ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • Windows7 64位系统安装PLSQL Developer的步骤和注意事项
    本文介绍了在Windows7 64位系统上安装PLSQL Developer的步骤和注意事项。首先下载并安装PLSQL Developer,注意不要安装在默认目录下。然后下载Windows 32位的oracle instant client,并解压到指定路径。最后,按照自己的喜好对解压后的文件进行命名和压缩。 ... [详细]
author-avatar
南方的狼1975
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有