动态数组的惯用初始化是否会调用未定义的行为?

2023-12-04

这个问题可能有点争议。 我在块范围内有以下代码:

int *a = malloc(3 * sizeof(int));
if (!a) { ... error handling ... }
a[0] = 0;
a[1] = 1;
a[2] = 2;

我认为这段代码调用了UB由于指针算术超出范围。 原因是,有效型对象指针的a从来没有 设置int[3]反而int仅有的。因此,对索引处的对象的任何访问 C 标准没有定义 0 以外的值。

原因如下:

Line a = malloc(...)。 如果分配成功则a足以存储 3 个区域的点ints.

a[0] = ...相当于*a = ...,l 值为int。它设置了有效型第一个的sizeof(int)字节到int如规则所示6.5p6.

...对于对没有声明类型的对象的所有其他访问,对象的有效类型只是用于访问的左值的类型。

现在指针a指向类型的对象int, not int[3].

a[1] = ...相当于*(a + 1) =。表达a + 1指向末尾后一个元素int对象可通过*a。 该指针本身对于比较有效,但访问未定义,因为:

Rule 6.5.6p7:

...指向不是数组元素的对象的指针的行为与指向长度为 1 的数组的第一个元素的指针相同,对象的类型作为其元素类型。

并统治6.5.6p8:

...如果结果指向数组对象的最后一个元素,则不应将其用作所计算的一元 * 运算符的操作数。

类似的问题与相关a[2] = ...但这里甚至a + 2隐藏在a[2]调用UB.

如果标准允许在有效内存区域进行任意指针算术,只要满足对齐要求和严格的别名规则,这个问题就可以得到解决。或者相同类型的连续对象的任何集合都可以视为数组。然而,我没能找到这样的东西。

如果我对标准的解释是正确的,那么某些 C 代码(全部?)将是未定义的。 因此,当我希望我能做到这一点时,这是罕见的情况之一wrong.

Am I?


该标准仅“半途而废”地定义了术语“对象”:它说每个对象都是一个存储区域,但它没有指定存储区域何时是对象或不是对象。对于大多数标准来说,可以说每个存储区域同时包含适合其中的所有类型的所有对象;任何修改对象的操作都会修改底层存储,任何修改底层存储的操作都会修改其中所有对象的存储值。

我认为很明显,标准的作者期望,在标准说某个操作调用未定义行为的情况下,但该行为将在没有该声明的情况下定义,质量实现应该以定义的方式运行如果他们的客户觉得有用。然而,这些情况属于哪些情况,属于标准管辖范围之外的实施质量问题。因此,如果标准将某些操作描述为未定义行为,而迄今为止所有实现都以同样明显有用的方式处理这些操作,那并不重要,因为没有人试图出售编译器,会将标准未能强制执行此类行为解释为邀请他们以对客户不利的方式偏离它。

由于不同的编译器用于不同的目的,因此标准实际上可以定义许多低级编程任务所需的所有行为,同时还允许对高端数字运算有用的所有优化,唯一的方法是要么识别进行不同优化的实现类别,要么添加更好的方法来邀请或阻止优化,这将有效地提高性能和/或导致不正确的程序行为。因为曾经存在或可能存在的每个编译器都会避免进行一些本来有用的优化,和/或执行错误地处理一些严格符合 C11 程序的“优化”,因此标准是否允许愚蠢的优化应该只与那些想要编写质量较差的编译器或想要竭尽全力与它们兼容的人相关。

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

动态数组的惯用初始化是否会调用未定义的行为? 的相关文章

  • 为什么大多数 C 开发人员使用 Define 而不是 const? [复制]

    这个问题在这里已经有答案了 在许多程序中 define与常量具有相同的用途 例如 define FIELD WIDTH 10 const int fieldWidth 10 我通常认为第一种形式优于另一种形式 它依赖于预处理器来处理基本上是
  • 为什么要序列化对象需要 Serialized 属性

    根据我的理解 SerializedAttribute 不提供编译时检查 因为它都是在运行时完成的 如果是这样 那么为什么需要将类标记为可序列化呢 难道序列化器不能尝试序列化一个对象然后失败吗 这不就是它现在所做的吗 当某些东西被标记时 它会
  • 从 MVC 迁移到 ASP.NET Core 3.1 中的端点路由时,具有角色的 AuthorizeAttribute 不起作用

    我正在尝试将我的项目从 UseMVC asp net core 2 2 兼容样式 升级到 UseEndpoint Routing 并且我的所有请求都被重定向到我的验证失败页面 它与声明有关 如果我删除 Authorize Roles Adm
  • 访问者和模板化虚拟方法

    在一个典型的实现中Visitor模式 该类必须考虑基类的所有变体 后代 在许多情况下 访问者中的相同方法内容应用于不同的方法 在这种情况下 模板化的虚拟方法是理想的选择 但目前这是不允许的 那么 模板化方法可以用来解析父类的虚方法吗 鉴于
  • 如何从 C# 控制器重定向到外部 url

    我使用 C 控制器作为网络服务 在其中我想将用户重定向到外部网址 我该怎么做 Tried System Web HttpContext Current Response Redirect 但没有成功 使用控制器的重定向 http msdn
  • 检查算术运算中的溢出情况[重复]

    这个问题在这里已经有答案了 可能的重复 检测 C C 中整数溢出的最佳方法 https stackoverflow com questions 199333 best way to detect integer overflow in c
  • 如何识别 WPF 文本框中的 ValidationError 工具提示位置

    我添加了一个箭头来指示工具提示中的文本框 当文本框远离屏幕边缘时 这非常有效 但是当它靠近屏幕边缘时 工具提示位置发生变化 箭头显示在左侧 Here is the Image Correct as expected since TextBo
  • C 语言中 =+(等于加)是什么意思?

    我碰到 与标准相反 今天在一些 C 代码中 我不太确定这里发生了什么 我在文档中也找不到它 In ancientC 版本 相当于 它的残余物与最早的恐龙骨头一起被发现 例如 B 引入了广义赋值运算符 使用x y to add y to x
  • 在 2D 中将一个点旋转另一个点

    我想知道当一个点相对于另一个点旋转一定角度时如何计算出新的坐标 我有一个块箭头 想要将其相对于箭头底部中间的点旋转角度 theta 这是允许我在两个屏幕控件之间绘制多边形所必需的 我无法使用和旋转图像 从我到目前为止所考虑的情况来看 使问题
  • 将数据打印到文件

    我已经超载了 lt lt 运算符 使其写入文件并写入控制台 我已经为同一个函数创建了 8 个线程 并且我想输出 hello hi 如果我在无限循环中运行这个线程例程 文件中的o p是 hello hi hello hi hello hi e
  • 当模板类不包含可用的成员函数时,如何在编译时验证模板参数?

    我有以下模板struct template
  • 迭代 my_dict.keys() 并修改字典中的值是否会使迭代器失效?

    我的例子是这样的 for my key in my dict keys my dict my key mutate 上述代码的行为是否已定义 假设my dict是一本字典并且mutate是一个改变其对象的方法 我担心的是 改变字典中的值可能
  • 获取 2 个数据集 c# 中的差异

    我正在编写一个简短的算法 它必须比较两个数据集 以便可以进一步处理两者之间的差异 我尝试通过合并这两个数据集并将结果更改放入新的数据集来实现此目标 我的方法如下所示 private DataSet ComputateDiff DataSet
  • 如何一步步遍历目录树?

    我发现了很多关于遍历目录树的示例 但我需要一些不同的东西 我需要一个带有某种方法的类 每次调用都会从目录返回一个文件 并逐渐遍历目录树 请问我该怎么做 我正在使用函数 FindFirstFile FindNextFile 和 FindClo
  • 什么是 __declspec 以及何时需要使用它?

    我见过这样的例子 declspec在我正在阅读的代码中 它是什么 我什么时候需要使用这个构造 这是 Microsoft 对 C 语言的特定扩展 它允许您使用存储类信息来赋予类型或函数属性 文档 declspec C https learn
  • 运算符“==”不能应用于“int”和“string”类型的操作数

    我正在编写一个程序 我想到了一个数字 然后计算机猜测了它 我一边尝试一边测试它 但我不断收到不应该出现的错误 错误是主题标题 我使用 Int Parse 来转换我的字符串 但我不知道为什么会收到错误 我知道它说 不能与整数一起使用 但我在网
  • 双精度类型二维多维数组的 pinvoke 编组作为 c# 和 c++ 之间的输入和输出

    我有以下我正在尝试解决的双物质类型的 2d 多维数组的 c 和 c pinvoke 编组 我已经查看了以下热门内容以获得我目前拥有的内容使用双精度数组进行 P Invoke 在 C 和 C 之间编组数据 https stackoverflo
  • 用于 C# XNA 的 Javascript(或类似)游戏脚本

    最近我准备用 XNA C 开发另一个游戏 上次我在 XNA C 中开发游戏时 遇到了必须向游戏中添加地图和可自定义数据的问题 每次我想添加新内容或更改游戏角色的某些值或其他内容时 我都必须重建整个游戏或其他内容 这可能需要相当长的时间 有没
  • 使用 Crypto++ 获取 ECDSA 签名

    我必须使用 Crypto 在变量中获取 ECDSA 签名 我在启动 SignMessage 后尝试获取它 但签名为空 我怎样才能得到它 你看过 Crypto wiki 吗 上面有很多东西椭圆曲线数字签名算法 http www cryptop
  • 是否可以在 C# 中强制接口实现为虚拟?

    我今天遇到了一个问题 试图重写尚未声明为虚拟的接口方法的实现 在这种情况下 我无法更改接口或基本实现 而必须尝试其他方法 但我想知道是否有一种方法可以强制类使用虚拟方法实现接口 Example interface IBuilder

随机推荐

  • PHP Pack/unpack - 它可以处理可变长度字符串吗

    我一直试图弄清楚 Pack Unpack 的 PHP 实现是否可以做 Perl 版本能够做的事情 我希望能够用 PHP 实现的示例是 http perldoc perl org perlpacktut html String Lengths
  • 如何在 C# 中的一个循环中重命名多个按钮

    我有一个类似战舰的程序 其中有 10 x 10 网格的按钮 在程序开始时 我希望所有按钮的文本都更改为 这表明没有人射击该坐标 我似乎找不到一种方法来重命名一个循环中的所有按钮 这些按钮都有名称 b00 b01 b02 显示它们的坐标 第一
  • 如何在 Xcode 8.3 中导入私有框架,而不会出现“架构 arm64 的未定义符号”

    我正在尝试使用 CDBatterySaver 打开低功耗模式 只需使用 CDBatterySaver batterySaver setMode 1 我知道没有与以前的 Xcode 相同类型的目录 因此这些方法不起作用 我也尝试过仅导入 h
  • 计算 A[i] 最右或最左且为 max 的段数

    给你一个数组 其中包含N整数 你必须回答K查询 每个查询包含一个整数X这是数组的 从 1 开始的索引 元素的索引 为每个查询计算以下内容 The number of segments containing the index X as th
  • 使用 SIFT 实现增强现实

    我遇到过很多 AR 库 SDK API 它们都是基于标记的 直到我发现这个视频 从描述和评论来看 他似乎正在使用 SIFT 来检测对象并跟踪它 我需要为 Android 执行此操作 因此我需要用纯 Java 完整实现 SIFT 我愿意这样做
  • 行图在 dc.js/crossfilter 中仅选择一个条形图?

    我有一个 dc rowchart 它有 5 个不同的 类别 最初 所有内容都被选中 当我单击其中一个时 只有该一个会突出显示 当我单击第二个时 我单击的第一个和第二个都会突出显示 如何制作 配置行图 以便每次单击栏时仅突出显示一个类别 dc
  • 自动化 Eclipse“Yui 压缩机...”

    日食光动力治疗有这个方便的内置功能唯压缩机在文件的上下文菜单中 但是 当构建使用多个此类文件的 Web 应用程序时 每次更新后手动压缩文件会变得很乏味 它甚至不记得哪些文件压缩为哪些文件名 因此您必须再次输入 是否可以在 Eclipse 中
  • 来自 AJAX 请求的 Post 参数在 ColdFusion 的表单范围内未定义

    我正在开发 ColdFusion 8 培训应用程序 其中我发出一些 AJAX 请求 没有任何库 例如 jQuery 来支持非常基本的 CRUD 应用程序 高层架构包括一个 CFM 视图 一个具有接收 AJAX 请求的远程访问方法的 CFC
  • 按钮边框颜色 - Objective C - Swift

    我想将边框颜色更改为特定的十六进制颜色 21CE99 你们能帮我吗 我已经知道如何将其更改为基本颜色 例如 button layer borderColor UIColor greenColor CGColor 但我只需要这个颜色 谢谢 A
  • 替换 UIView 的 contentStretch?

    在 iOS 6 0 中 UIView 的 contentStretch 属性已被弃用 如何使用新 旧 其他 API 实现相同的功能 我正在寻找的功能是在 UIButton 上仅拉伸图像的一部分 除了边缘之外的所有内容 使用 ressized
  • NSNotificationCenter 关于 ViewWillAppear 和 ViewWillDisapper

    我有一个简单的 viewController 我想听UIKeyboardWillHideNotification 因此我有以下代码 void viewWillAppear BOOL animated super viewWillAppear
  • Android 7.0 上的 Xamarin 错误 System.DllNotFoundException:/system/lib/libsqlite.so

    每当我尝试在 android 7 0 中创建 SQLite Net SQLiteConnection 时 都会出现此异常 知道如何修复它吗 我正在使用这些 nuget 包
  • 将 Underscore 模块与 Node.js 结合使用

    我一直在学习 Node js 和模块 但似乎无法让 Underscore 库正常工作 似乎我第一次使用 Underscore 中的函数时 它会覆盖 对象 结果为我的函数调用 有人知道发生了什么事吗 例如 以下是来自 node js REPL
  • 将函数应用于屏蔽 numpy 数组

    我有一个作为 numpy 数组的图像和一个图像掩码 from scipy misc import face img face gray True mask img gt 250 如何将函数应用于所有屏蔽元素 def foo x return
  • Vuejs - 未定义需求

    我只是在玩弄 vuejs 路由器并尝试加载组件 我使用了示例代码并进行了更改foo Define some components var Foo Vue extend template require components test vue
  • 资产管道、指南针字体和 eot?iefix 对字体的调用

    我正在尝试使用 Compass font face mixin 其中包含 eot iefix 我的应用程序 资产 字体包含所需的所有字体类型 包括 eot 当我尝试运行 asset precompile 时 任务失败 并显示如下内容 web
  • 在您的项目中找不到有效的 GoogleService-Info.plist

    当我使用 Xcode 9 beta 4 运行 swift 3 2 代码时 出现以下错误 Terminating app due to uncaught exception com firebase core reason FIRApp co
  • Android - 广播接收器没有被触发

    我知道这里已经被问了很多 但我已经在互联网上搜索了几个小时 我什至重复使用了以前的一些代码来接收短信 但我什么也没得到 因此 这里是接收短信的基本应用程序 但该应用程序从未收到意图 我认为如果文本是从同一部手机发送的 则意图可能会被忽略 但
  • 尽管为“子视图”赋予了值,但无法将空子视图添加到 ViewGroup

    我的应用程序在启动时立即崩溃 由于某种原因 它声明它是一个 IllegalArgumentException 尽管我不明白为什么 我已经正确实例化了 setContentView 我尝试仅在没有 R id 的情况下将参数设置为 Activi
  • 动态数组的惯用初始化是否会调用未定义的行为?

    这个问题可能有点争议 我在块范围内有以下代码 int a malloc 3 sizeof int if a error handling a 0 0 a 1 1 a 2 2 我认为这段代码调用了UB由于指针算术超出范围 原因是 有效型对象指