对有效的类型规则感到困惑

2024-02-07

我似乎再次错过了有关有效类型的一些难题......代码中的注释本质上是我的问题,但这是我能想到在适当的上下文中提出这个问题的唯一方法。

#include <stdlib.h>
#include <string.h>

typedef struct foo {
    int n;
} Foo;

int main(void)
{
    // No effective type yet because there has been no write to the memory.
    Foo *f = malloc(sizeof(Foo));

    // Effective type of `f` is now `Foo *`, except I'm writing to
    // `f->n`, so shouldn't it be `int *`? Not sure what's going on here.
    f->n = 1;

    // No effective type yet because there has been no write to the memory.
    char *buf = malloc(sizeof(Foo));

    // Effective type of `buf` is `Foo *`, despite it being declared as
    // `char *`.
    // It's not safe to modify `buf` as a `char` array since the effective type
    // is not `char`, or am I missing something?
    memcpy(buf, f, sizeof(Foo));

    // The cast here is well defined because effective type of `buf` is
    // `Foo *` anyway, right?
    ((Foo *)buf)->n++;

    // I'm not even sure this is OK. The effective type of `buf` is `Foo *`,
    // right? Why wouldn't it be OK then?
    memcpy(f, buf, sizeof(Foo));

    // Safe if the last `memcpy` was safe.
    f->n++;

    // buf now points to invalid memory.
    free(buf);

    // Pointers with different declared types point to the same object,
    // but they have the same effective type that is not qualified by
    // `restrict`, so this doesn't violate strict aliasing, right?
    // This is allowed because `f` was allocated via `malloc`,
    // meaning it is suitably aligned for any data type, so
    // the effective type rules aren't violated either.
    buf = (void *)f;

    // `f`, and consequently `buf` since it points to the same object as `f`,
    // now point to invalid memory.
    free(f);
}

我认为所有这些都可以是正确的,还是在某些情况下我是错误的?我意识到这是在问多个问题,但我本质上是在问我对有效类型和严格别名的理解是否正确。 GCC 没有为我提供任何诊断信息-pedantic-errors -Wextra -Wall -O2 -fstrict-aliasing -Wstrict-aliasing


您似乎对“有效类型”的适用范围感到困惑:它适用于 malloc 空间,而不是任何指针。与 C 中一样,指针是一个单独的对象,具有指向指针可能指向的任何空间的单独属性。

f是一个(命名)变量,因此其有效类型始终与其声明类型相同,即Foo *。相似地buf的有效类型始终是char *。有效类型在运行时可能改变的唯一一次是动态分配的空间。

您的要点和代码注释没有什么意义,因此我决定重新注释您的代码。在每种情况下,文本均指文本上方的代码:

Foo *f = malloc(sizeof(Foo));

好的。未初始化的字节已被分配并且f指向他们。动态分配的空间还没有有效的类型。

f->n = 1;

第一种有效类型sizeof(int)动态分配空间的字节设置为int。 (* - 但请参阅脚注)

char *buf = malloc(sizeof(Foo));
memcpy(buf, f, sizeof(Foo));

The memcpy函数保留复制对象的有效类型,因此第一个对象的有效类型sizeof(int)指向的空间的字节数buf, is int.

((Foo *)buf)->n++;

首先,演员阵容不存在对齐问题,因为malloc对于任何类型,空间都正确对齐。继续访问n,这是可以的,因为((Foo *)buf)->n是类型的左值int,它指定一个有效类型的对象int。这样我们就可以毫无问题地读写。

memcpy(f, buf, sizeof(Foo));

memcpy总是可以的,因为它设置了有效类型(您的评论表明 memcpy 在某些情况下可能不正常)。该行设置了所指向的空间的有效类型f, to int(因为源空间具有有效类型int).

f->n++;

很好,道理一样((Foo *)buf)->n++ above.

free(buf);
buf = (void *)f;

冗余演员阵容。所指向的空间f有有效类型int尽管如此,因为这两行都没有写入该空间。

free(f);

没问题。


脚注:有些人对这个表达有不同的解释f->n (or ((Foo *)buf)->nw.r.t.严格的别名。他们说f->n定义为(*f).n因此相关的有效类型是*f,不是类型f->n。我不同意这个观点,所以不再赘述。有人建议 C2X 澄清这种情况以及严格混叠的其他灰色区域。对于您的特定代码,该代码在任何一种解释下仍然是正确的。

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

对有效的类型规则感到困惑 的相关文章

  • C# 锁(mylocker) 不起作用

    我有很多 Web 服务调用 异步 在回调中 我会将结果绘制到 Excel 中 我想同步绘图方法 所以我使用以下内容 但是 从我在 Visual Studio 中追踪到 每次 lock locker 都会成功 并且有许多线程运行clearco
  • 了解 VerQueryValue

    在 MSDN 上 我注意到 VerQueryValue 函数的以下内容 lplp缓冲区 输出 低电压空洞当此方法返回时 包含指向 pBlock 指向的缓冲区中所请求版本信息的指针的地址 当关联的 pBlock 内存被释放时 lplpBuff
  • 在单个 C# 泛型方法中返回可为 null 和 null?

    C 泛型方法是否可以返回对象类型或 Nullable 类型 例如 如果我有一个安全的索引访问器List我想返回一个值 稍后我可以使用以下任一方法检查该值 null or HasValue 目前我有以下两种方法 static T SafeGe
  • 纹理映射 C++ OpenGL

    我已经阅读了相关内容 包括 Nehe 和此处的解决方案 但我找不到具体的答案 我正在尝试加载一张名为stars jpg 的照片 我想通过使用 uv 坐标映射它来使其成为场景的背景 方法是 glBegin GL QUADS glTexCoor
  • 在 PHP 扩展中,推荐从 std::string 返回值的方法

    我们有一个简单的 PHP 函数 其目的是调用 C 自由函数std string callLibrary std string 并返回其std string返回值 目前看起来是这样的 PHP FUNCTION call library cha
  • 如何让BackgroundWorker返回一个对象

    我需要做RunWorkerAsync 返回一个List
  • 为什么数组不可赋值? [复制]

    这个问题在这里已经有答案了 据我所知 C 标准禁止使用数组作为可修改的左值 即在赋值的左侧 int lhs 4 rhs 4 0 1 2 3 lhs rhs illegal 现在 我一直想知道为什么会这样 我可以看到上面的语句 以及写入数组的
  • MouseDoubleClick 事件不会冒泡

    我的场景经过简化 我有一个包含员工行的 ListView 在每个员工行中 都有 增加 和 减少 按钮来调整他的工资 假设在我的程序中 双击 员工 行意味着 解雇此人 The problem是当我快速单击 增加 时 这会触发 ListView
  • C++在子类中调用虚方法

    我有以下课程 class A protected A inner public virtual void doSomething 0 class B public A void doSomething if inner NULL inner
  • C# While 循环与 For 循环?

    在 C 中 一个问题已经困扰我一段时间了 它的 While 和 For 循环之间的实际主要区别是什么 它只是纯粹的可读性吗 在 for 循环中本质上可以做的所有事情都可以在 while 循环中完成 只是在不同的地方 举这些例子 int nu
  • 扩展一个类

    编辑回答 虽然我最初的问题并没有完全按照康拉德 鲁道夫提供的答案所解决的方式解释我的需求 但他 无意或有意 基本上为我写了我想写的内容 类本身不会被扩展 但通过使类了解新函数来扩展其功能 这些新函数允许它 类 处理更广泛的问题 我非常感谢您
  • OpenMP 和 C++:this 指针

    Is thisOpenMP 中始终共享指针 尽管编译器不会抱怨以下代码default none pragma omp parallel for default none shared n for SInt i 0 i lt n i f i
  • cmake 包括其他目录中的 h 文件

    我在 cmake 项目下进行测试时遇到问题 我的项目是这样安排的 TerrainMap PointAccumulator heightQuadGrid Test 在 TerrainMap 目录中 CMakeLists txt 文件简单地概述
  • 如何查明我的字符串是否包含“micro”Unicode 字符?

    我有一个包含实验室数据的 Excel 电子表格 如下所示 g L ppb 我想测试希腊字母 是否存在 如果发现我需要做一些特别的事情 通常 我会写这样的东西 if cell StartsWith matchSequence lt unive
  • Sharepoint 的 CAML 查询中的日期时间比较

    我正在尝试从共享点列表中获取某些项目 具体取决于自定义列中的日期 我已经使用 U2U Caml Builder 创建了查询 这很有效 但是当我将其放入 Web 部件中自己的代码中时 它总是返回列表中的所有项目 这是我的代码 DateTime
  • 如何重写(重新实现)QFileSystemModel 中的成员函数

    我已经为此苦苦挣扎了一段时间 Qt s QFileSystemModel由于图标获取算法非常糟糕 在获取数百个文件时速度非常慢 我想完全禁用图标 它们被提取到QFileSystemModel data方法不是虚拟的 QFileSystemM
  • QT C++ QRegularExpression 多个匹配

    我想使用正则表达式从 QString html 中提取信息 我明确想使用正则表达式 无解析器解决方案 和类Q正则表达式 http qt project org doc qt 5 0 qtcore qregularexpression htm
  • 如何将 IDispatch* 放入托管代码中

    我一直在考虑尝试使用 C 编写一个实现 OPOS 服务对象的 COM 对象 我已经使用自动化和 MFC 在 C 中完成了它 这并不太困难 所以我坚持尝试将其转换为一种方法 我将排除界面中的其他方法 因为它们很简单 或者我希望如此 id 6
  • C++11 中引入了哪些重大更改?

    我知道 C 11 中至少有一项更改会导致一些旧代码停止编译 引入explicit operator bool 在标准库中 替换旧实例operator void 诚然 这将破坏的代码可能是一开始就不应该有效的代码 但它仍然是一个破坏性的变化
  • 如何在 C# 中将 json 转换为平面结构

    我正在尝试用 C 编写函数 将 JSON 转换为键 值对 它应该支持数组 例如下面的 JSON title title value components component id id1 menu title menu title1 tit

随机推荐

  • 将 musicbrainz URI 映射到 Spotify URI

    有谁知道如何找到给定艺术家 专辑的 musicbrainz URI 的 Spotify URI Spotify 的 web api 不能解决我的问题 因为我想映射所有 musicbrainz 艺术家和专辑 但速度很慢 您应该能够使用 Ech
  • Android Studio 3.1:找不到 org.jetbrains.trove4j:trove4j:20160824

    昨天 我将 Android Studio 更新到 3 1 但收到此错误 Could not find org jetbrains trove4j trove4j 20160824 Searched in the following loca
  • Blobstore 上传 + Ajax/替代方案

    下面的代码可以完美运行 我唯一关心的是我想将下面的内容转换为 AJAX alternative 这样就不需要刷新整个页面来提交此请求 如果可能的话 还包括加载进度条等
  • 在节点中使用 zone.js 挂钩

    我正在尝试使用编写一个简单的演示角度 zone js https github com angular zone js在节点中 但由于某种原因既没有beforeTask or afterTask正在被召唤 这是我正在运行的代码 requir
  • Indy 10 中的 TIdHTTP

    我以前在 Delphi 6 天时就使用过 Indy 现在我正在使用 Indy 10 我想做的事情非常简单 但我没有看到简单的方法 所以我一定错过了一些东西 我想做的是这样的 这是我正在使用的实际代码 procedure TForm1 btn
  • 如何从 URL 流式传输/下载和播放音频?

    我需要在 iOS 上运行的 Unity3D 中流式传输或下载并播放从 URL 获取的音频 音频来自文本转音频服务 我需要在 Unity 上播放它 我一上午都在谷歌上搜索 没有找到有效的解决方案 Unity3D文档中有一个代码片段 WWW音频
  • 从Java访问gradle资源

    我有一个具有这种结构的基于 gradle 的 java 项目 myproject src main java resources myresource xml build classes main myresource xml resour
  • 雅虎财经 V7 API 现在需要 cookie? (Python)

    url https query2 finance yahoo com v7 finance quote symbols TSLA fields regularMarketPreviousClose region US lang en US
  • 在使用 fit_generator 和 evaluate_generator 训练网络时,如何绘制 AUC 和 ROC?

    我正在使用生成器来训练和预测数据的分类 这是一个例子图像数据生成器 https blog keras io building powerful image classification models using very little da
  • 在同一服务器上加载同一项目的不同版本的配置文件的最佳方法是什么?

    我有一个大型 php 项目 依赖于两个级别的配置文件 在我的项目文件夹中 我有一个 default config ini 它被加载 然后与站点特定的配置文件合并 目前代码正在读取环境变量PROJECT CONFIG指向特定的配置文件 这对于
  • 我应该通过 SessionAware 还是 ActionContext 获取会话?

    在阅读了通过以下方式获取会话映射之间的差异之后ActionContext getContext getSession 并让它注入SessionAware我想知道哪种方法是首选方法 为什么 该API推荐使用SessionAware 我在网上读
  • 为什么 GetMessageW 会在我的 WPF 应用程序中占用大量 CPU 使用率?

    我在这里遇到了一个严重的难题 我正在调查应用程序中 WPF 组件的性能问题 我们的 net 应用程序非常大 并且几乎完全采用 Windows 窗体 作为新计划的一部分 我们使用丰富的 WPF 用户界面重写了我们的核心组件之一 有很多 Win
  • 为什么 git merge 有时会创建提交,有时不会?

    当我做git merge从另一个分支到当前工作区 git 有时会进行新的提交 Merge remote tracking branch xxx into xxx 有时 它不会 Fast forward src files 那么什么决定了是否
  • Mongoose findOne 在嵌套记录上无法按预期工作

    我在 MongoDB 中有一个集合 其简化版本如下所示 Dealers Id 123 Name Someone Email email protected cdn cgi l email protection Vehicles Id 123
  • 找不到 momd 文件:核心数据问题

    噢天啊 我搞砸了一些事情 我是一名 Core Data 菜鸟 正在开发我的第一个 iOS 应用程序 经过多次堆栈溢出后 我正在使用以下代码 NSString path NSBundle mainBundle pathForResource
  • Go 如何处理 Google App Engine 上的并发请求

    我对 Go 如何处理 Google App Engine 上的并发请求有点困惑 所以我希望有人能提供一些澄清 以下是我收集到的事实 Go 在 App Engine 上是单线程的 这是因为可以通过使用多个线程创建竞争条件来执行任意指针算术 h
  • 离子降低滚动速度

    我在尝试从此代码减慢滚动速度时遇到问题 ionicScrollDelegate getByHandle credit scrollBottom true 我怎样才能减慢滚动速度 因为现在它对我来说滚动得太快了 我需要放慢滚动速度 就像星球大
  • Python - 安装有扩展的远程 Webdriver

    我想使用以下命令在不同浏览器版本上测试一个扩展浏览器堆栈 http browserstack com 这是一个返回具有指定功能的驱动程序的函数 我有一个 crx file对于 Chrome 和 xpi file对于我本地计算机上的 Fire
  • 在屏幕上查找复合位置

    我正在 Java 中为 SWT 和 AWT 实现一个屏幕键盘 一件重要的事情是将键盘移动到可以显示所选文本字段的位置 并且不要位于屏幕键盘后面 对于 AWT 我可以检测当前选定组件的位置 Component owner KeyboardFo
  • 对有效的类型规则感到困惑

    我似乎再次错过了有关有效类型的一些难题 代码中的注释本质上是我的问题 但这是我能想到在适当的上下文中提出这个问题的唯一方法 include