理解 void 指针

2023-12-21

In my answer https://stackoverflow.com/a/46234805/2411320我提到取消引用void指针是一个坏主意。但是,当我这样做时会发生什么?

#include <stdlib.h>
int main (void) {
 void* c = malloc(4);
 *c;
 &c[0];
}

汇编:

gcc prog.c -Wall -Wextra
prog.c: In function 'main':
prog.c:4:2: warning: dereferencing 'void *' pointer
  *c;
  ^~
prog.c:5:4: warning: dereferencing 'void *' pointer
  &c[0];
    ^
prog.c:5:2: warning: statement with no effect [-Wunused-value]
  &c[0];
  ^

对于那些说这没有发生的人来说,这是来自 Wandbox 的图片:

and a Live demo in Ideone.

它实际上会尝试读取内存中的内容c指向has,然后获取该结果,但最终实际上什么也没做?或者这一行根本没有任何效果(但是 GCC 不会产生警告)。

我认为,由于编译器对数据类型一无所知,因此在不知道类型大小的情况下,它无法做太多事情。

为什么取消引用void*不会产生错误,而只是警告?


如果我尝试分配,我会收到错误:

void 表达式的使用无效

但单独取消引用不应该产生错误吗?


C 标准明确指出5.1.1.3p1 http://port70.net/%7Ensz/c/c11/n1570.html#5.1.1.3:

符合要求的实施应产生至少一条诊断消息(以实现定义的方式标识)如果预处理翻译单元或翻译单元包含违反任何语法规则或约束的行为,即使该行为也显式指定为未定义或实现定义。在其他情况下不需要产生诊断消息。 9)

脚注 9 说

其目的是实施应识别每项违规行为的性质,并在可能的情况下定位每项违规行为。当然,只要仍然正确翻译有效的程序,实现就可以自由地产生任意数量的诊断。它还可能成功翻译无效程序。

因此,GCC 完全符合 C 标准。您的程序是无效程序。只需要一条诊断消息 - 并且允许编译器成功翻译您的无效程序。由于海湾合作委员会有一个非标准扩展为空指针算术 https://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html:

在 GNU C 中,指针支持加法和减法运算void以及指向函数的指针。这是通过处理 a 的大小来完成的void或函数为1.

这样做的一个后果是sizeof也允许void以及函数类型,并返回1.

选项-Wpointer-arith如果使用这些扩展,则请求警告。

它决定对您的无效程序执行一些“明智”的操作并成功翻译它。


请注意,未评估的取消引用指向空指针已经需要在sizeof, 因为:

void *foo;
sizeof *foo;

必须匹配

sizeof (void);

它们的计算结果都为 1,因此更容易允许丢弃指向 void 的指针的取消引用到处.


正如 Lundin 所说,如果您想要约束违规的实际错误,请使用-std=c11 -pedantic-errors.

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

理解 void 指针 的相关文章

  • 没有强命名的代码签名是否会让您的应用程序容易被滥用?

    尝试了解authenticode代码签名和强命名 我是否正确地认为 如果我对引用一些 dll 非强命名 的 exe 进行代码签名 恶意用户就可以替换我的 DLL 并以看似由我签名但正在运行的方式分发应用程序他们的代码 假设这是真的 那么您似
  • WCF RIA 服务 - 加载多个实体

    我正在寻找一种模式来解决以下问题 我认为这很常见 我正在使用 WCF RIA 服务在初始加载时将多个实体返回给客户端 我希望两个实体异步加载 以免锁定 UI 并且我想利用 RIA 服务来执行此操作 我的解决方案如下 似乎有效 这种方法会遇到
  • Web 客户端和 Expect100Continue

    使用 WebClient C NET 时设置 Expect100Continue 的最佳方法是什么 我有下面的代码 我仍然在标题中看到 100 continue 愚蠢的 apache 仍然抱怨 505 错误 string url http
  • 为什么两个不同的 Base64 字符串的转换会返回相等的字节数组?

    我想知道为什么从 base64 字符串转换会为不同的字符串返回相同的字节数组 const string s1 dg const string s2 dq byte a1 Convert FromBase64String s1 byte a2
  • 查找c中结构元素的偏移量

    struct a struct b int i float j x struct c int k float l y z 谁能解释一下如何找到偏移量int k这样我们就可以找到地址int i Use offsetof 找到从开始处的偏移量z
  • HTTPWebResponse 响应字符串被截断

    应用程序正在与 REST 服务通信 Fiddler 显示作为 Apps 响应传入的完整良好 XML 响应 该应用程序位于法属波利尼西亚 在新西兰也有一个相同的副本 因此主要嫌疑人似乎在编码 但我们已经检查过 但空手而归 查看流读取器的输出字
  • OleDbDataAdapter 未填充所有行

    嘿 我正在使用 DataAdapter 读取 Excel 文件并用该数据填充数据表 这是我的查询和连接字符串 private string Query SELECT FROM Sheet1 private string ConnectStr
  • Clang 3.1 + libc++ 编译错误

    我已经构建并安装了 在前缀下 alt LLVM Clang trunk 2012 年 4 月 23 日 在 Ubuntu 12 04 上成功使用 GCC 4 6 然后使用此 Clang 构建的 libc 当我想使用它时我必须同时提供 lc
  • 如何从 appsettings.json 文件中的对象数组读取值

    我的 appsettings json 文件 StudentBirthdays Anne 01 11 2000 Peter 29 07 2001 Jane 15 10 2001 John Not Mentioned 我有一个单独的配置类 p
  • 不同枚举类型的范围和可转换性

    在什么条件下可以从一种枚举类型转换为另一种枚举类型 让我们考虑以下代码 include
  • C#中如何移动PictureBox?

    我已经使用此代码来移动图片框pictureBox MouseMove event pictureBox Location new System Drawing Point e Location 但是当我尝试执行时 图片框闪烁并且无法识别确切
  • 带动态元素的 WPF 启动屏幕。如何?

    我是 WPF 新手 我需要一些帮助 我有一个加载缓慢的 WPF 应用程序 因此我显示启动屏幕作为权宜之计 但是 我希望能够在每次运行时更改屏幕 并在文本区域中显示不同的引言 这是一个生产力应用程序 所以我将使用非愚蠢但激励性的引言 当然 如
  • 显示UnityWebRequest的进度

    我正在尝试使用下载 assetbundle统一网络请求 https docs unity3d com ScriptReference Networking UnityWebRequest GetAssetBundle html并显示进度 根
  • 覆盖子类中的字段或属性

    我有一个抽象基类 我想声明一个字段或属性 该字段或属性在从该父类继承的每个类中具有不同的值 我想在基类中定义它 以便我可以在基类方法中引用它 例如覆盖 ToString 来表示 此对象的类型为 property field 我有三种方法可以
  • 如何从两个不同的项目中获取文件夹的相对路径

    我有两个项目和一个共享库 用于从此文件夹加载图像 C MainProject Project1 Images 项目1的文件夹 C MainProject Project1 Files Bin x86 Debug 其中有project1 ex
  • 为什么编译时浮点计算可能不会得到与运行时计算相同的结果?

    In the speaker mentioned Compile time floating point calculations might not have the same results as runtime calculation
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags
  • IEnumreable 动态和 lambda

    我想在 a 上使用 lambda 表达式IEnumerable
  • Windows 和 Linux 上的线程

    我在互联网上看到过在 Windows 上使用 C 制作多线程应用程序的教程 以及在 Linux 上执行相同操作的其他教程 但不能同时用于两者 是否存在即使在 Linux 或 Windows 上编译也能工作的函数 您需要使用一个包含两者的实现
  • 使用.NET技术录制屏幕视频[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有没有一种方法可以使用 NET 技术来录制屏幕 无论是桌面还是窗口 我的目标是免费的 我喜欢小型 低

随机推荐

  • from Gui import * 在 python 3 中?

    我正在尝试这个 import os sys from Gui import import Image as PIL import ImageTk class ImageBrowser Gui def init self Gui init s
  • 通过PowerShell + WinRM传递双引号

    我正在用这个code https stackoverflow com a 13284313 1118239在服务器上执行远程代码 MSI 安装 通过脚本传递双引号是行不通的 我尝试了下面给出的两种变体 3 和 4 以及输出 输入 1 测试命
  • Rails 4 has_secure_password 呈现密码确认可选

    我使用 Rails 4有安全密码在我的用户模型中 技巧说如果我不设置 password confirmation 它永远不会被触发 但为什么当我运行测试时我会收到错误 密码确认不能为空如下 Failures 1 User Failure E
  • 在 Linq to SQL 中连接两个表

    也许是一个非常简单的问题 但我是 Linq to SQL 的新手 我有两张桌子 User UserId name Password Email USER TABLE Id UserId FirstName LastName 我想要一个查询
  • BufferGeometry 偏移量和索引

    我只是想知道 偏移量 和 索引 索引 到底是什么 偏移量例如中提到的https github com mrdoob Three js blob dev src core BufferGeometry js https github com
  • Python 中的桑基图

    有没有一个Python库可以生成桑基图 http en wikipedia org wiki Sankey diagram 我见过这个桑基图应用程序和库列表 http www sankey diagrams com sankey diagr
  • 从一维张量中提取前 k 个值索引

    给定 Torch 中的一维张量 torch Tensor 包含可以比较的值 比如浮点 我们如何提取顶部的索引k该张量中的值 除了暴力方法之外 我还在寻找 Torch lua 提供的一些 API 调用 它可以有效地执行此任务 截至拉取请求 4
  • 如何用动画从 UITableView 中删除行?

    我在从表视图中删除行时遇到问题 当按下行中的删除按钮时 我使用下面的代码 NSIndexPath indexPath NSIndexPath indexPathForRow control tag 100 inSection 0 resul
  • realm-js - 将本地领域数据复制到同步领域

    我在用realm js使用 React Native 在用户的设备上存储数据 并且工作流程中的某个点我想将本地领域中的所有数据复制到同步领域 以保留在 ROS 上 我遇到了一个问题 在我们的模式中 我们通过将引用一个对象的属性添加到另一个对
  • 如何根据对象字符串属性在 Xcode 中设置条件断点?

    我希望能够让调试器在达到特定字符串匹配时中断 举个例子 我可能有这样的事情 Foo myObj self gimmeObj myObj可能有一个名为name 我希望调试器在分配时停止 myObj name isEqualToString B
  • 红外发射器和 Android 5.0

    我在运行 Android 5 0 的 Galaxy S5 上遇到了红外发射器问题 在我更新到 5 0 之前 我的应用程序在我的手机上运行得很好 但现在 我要管理的设备没有任何反应 当我单击应用程序发送红外代码时 LED 指示灯会闪烁 表示红
  • 文本框为空问题

    我的 Access 表单上有一个文本框和一个按钮 在按钮的单击事件中 我想查看文本框是否为空 如果是 则不会执行任何操作 所以我用 If Me textbox Value Null Then Exit Sub End if 但它不起作用 我
  • 如何使用 Apache HttpClient 在 Post 请求中对俄语文本进行编码?

    有如下Java代码 public static void register UserInfo info throws ClientProtocolException IOException JSONException Registratio
  • 使用 Play Framework 作为组件

    我正在尝试添加 Play Framework Web 服务器作为较大应用程序的一部分 但该应用程序的主要用途不是 Web 服务器 它已经接受各种连接 包括串行和 TCP 但我需要添加 WebSocket 并且 Play Framework
  • 为什么 script-src-elem 不使用 script-src 中的值作为后备?

    在实现 csp header 时 我将我的策略指定为 default src self script src www gstatic com 由于我还没有声明script src elem我的 CSP 政策中的指令 如中所述this htt
  • 你怎么知道 R 中的哪些函数被标记为调试?

    我一直在使用debug 现在更频繁了 但有时我想知道哪些函数已被标记为调试 我知道你可以使用isdebugged 查明某个特定函数是否被标记 但是R有没有办法列出所有正在调试的函数呢 这很复杂 但它有效 find debugged func
  • Scala 对象的唯一 ID

    在Python中 id x 给出了对象x的唯一id Scala 中的等价物是什么 gt gt gt id True 1166096 gt gt gt id False 1166108 gt gt gt x id 1 2 3 gt gt gt
  • 如何:elastic beanstalk + 部署 docker + 正常关闭

    嗨 StackOverflow 的伟大人们 我们在 EB 上托管一个 docker 容器 并在其上运行基于 Nodejs 的代码 当重新部署我们的 docker 容器时 我们希望旧容器能够正常关闭 我找到了有关我们的代码如何接收由 dock
  • Javascript 静态/单例 - this 与 this 与对象名称

    这是一个关于性能和最佳实践的问题 假设我有一个js对象 封装了大量的helper方法 该对象被视为静态类 这意味着它永远不会被实例化 并且它的所有方法基本上都是辅助方法 当使用事件和 jQuery 时 对象的this范围不断变化 并且由于它
  • 理解 void 指针

    In my answer https stackoverflow com a 46234805 2411320我提到取消引用void指针是一个坏主意 但是 当我这样做时会发生什么 include