通过预定义的静态地址访问寄存器在 C++ 中是未定义的行为吗?

2023-12-25

我正在编译一个 C++ 程序以在独立环境中运行,并且我正在运行的 CPU 定义了一个可用的 32 位外设寄存器(编辑:内存映射) at PERIPH_ADDRESS(正确对齐,并且不与任何其他 C++ 对象、堆栈等重叠)。

我编译以下代码PERIPH_ADDRESS预定义,稍后将其与完整程序链接并运行它。

#include <cstdint>

struct Peripheral {
    const volatile uint32_t REG;
};

static Peripheral* const p = reinterpret_cast<Peripheral*>(PERIPH_ADDRESS);

uint32_t get_value_1() {
    return p->REG;
}

static Peripheral& q = *reinterpret_cast<Peripheral*>(PERIPH_ADDRESS);

uint32_t get_value_2() {
    return q.REG;
}

extern Peripheral r;
// the address of r is set in the linking step to PERIPH_ADDRESS

uint32_t get_value_3() {
    return r.REG;
}

是否有任何get_value函数(直接或通过p/q)有未定义的行为?如果是的话,我可以修复它吗?

我认为一个等效的问题是:任何符合标准的编译器都可以拒绝为我编译预期的程序吗?例如,一台已打开 UB 消毒器的设备。

我看过[基本.stc.动态.安全 http://eel.is/c++draft/basic.stc.dynamic.safety] and [basic.compound#def:object_pointer_type http://eel.is/c++draft/basic.compound#def:object_pointer_type] 但这似乎只限制了指向动态对象的指针的有效性。我认为它不适用于这段代码,因为“对象”位于PERIPH_ADDRESS从未被假定为动态的。我想我可以有把握地说,由p永远不会到达其存储期限的末尾,可以考虑static.

我也看过为什么 C++ 不允许从有效地址和类型创建有效指针? https://stackoverflow.com/questions/53200002/why-does-c-disallow-the-creation-of-valid-pointers-from-a-valid-address-and-ty以及对该问题的回答。它们也只引用动态对象的地址及其有效性,因此它们不回答我的问题。

我考虑过但无法回答自己的其他问题可能有助于解决主要问题:

  • 我是否会遇到任何 UB 问题,因为该对象从未在 C++ 抽象机中构造过?
  • 或者我实际上可以认为该对象是一个具有正确“构造”的静态存储持续时间的对象吗?

显然,我更喜欢引用任何最新 C++ 标准的答案。


指针强制转换的含义是由实现定义的[expr.reinterpret.cast] https://timsong-cpp.github.io/cppwp/expr.reinterpret.cast#5.sentence-2

整型或枚举类型的值可以显式转换为指针。转换为足够大小的整数(如果实现中存在这样的整数)并返回到相同指针类型的指针将具有其原始值;指针和整数之间的映射是由实现定义的。

Therefore this is well-defined. If your implementation promises you the result of the cast is valid, you are fine.

链接的问题是关于指针算术的,这与当前的问题无关。

† By definition, a valid pointer https://timsong-cpp.github.io/cppwp/basic.compound#3 points to an object, implying subsequent indirections are also well-defined. Care should be exercised in making sure the object is within its lifetime https://timsong-cpp.github.io/cppwp/basic.life#7.

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

通过预定义的静态地址访问寄存器在 C++ 中是未定义的行为吗? 的相关文章

  • UTF8/UTF16 和 Base64 在编码方面有什么区别

    In c 我们可以使用下面的类来进行编码 System Text Encoding UTF8 System Text Encoding UTF16 System Text Encoding ASCII 为什么没有System Text En
  • 属性对象什么时候创建?

    由于属性实际上只是附加到程序集的元数据 这是否意味着属性对象仅根据请求创建 例如当您调用 GetCustomAttributes 时 或者它们是在创建对象时创建的 或者 前两个的组合 在由于 CLR 的属性扫描而创建对象时创建 从 CLR
  • Signalr 在生产服务器中总是陷入长轮询

    当我在服务器中托管应用程序时 它会检查服务器端事件并始终回退到长轮询 服务器托管环境为Windows Server 2012 R1和IIS 7 5 无论如何 我们是否可以解决这个问题 https cloud githubuserconten
  • 如何在C++中实现模板类协变?

    是否可以以这样一种方式实现类模板 如果模板参数相关 一个对象可以转换为另一个对象 这是一个展示这个想法的例子 当然它不会编译 struct Base struct Derived Base template
  • fgets() 和 Ctrl+D,三次才能结束?

    I don t understand why I need press Ctrl D for three times to send the EOF In addition if I press Enter then it only too
  • C# 中值类型和引用类型有什么区别? [复制]

    这个问题在这里已经有答案了 我知道一些差异 值类型存储在堆栈上 而引用类型存储在托管堆上 值类型变量直接包含它们的值 而引用变量仅包含对托管堆上创建的对象位置的引用 我错过了任何其他区别吗 如果是的话 它们是什么 请阅读 堆栈是一个实现细节
  • 跨多个控件共享事件处理程序

    在我用 C 编写的 Windows 窗体应用程序中 我有一堆按钮 当用户的鼠标悬停在按钮上时 我希望按钮的边框发生变化 目前我有以下多个实例 每个按钮一个副本 private void btnStopServer MouseEnter ob
  • 如何针对 Nancy 中的 Active Directory 进行身份验证?

    这是一篇过时的文章 但是http msdn microsoft com en us library ff650308 aspx paght000026 step3 http msdn microsoft com en us library
  • 编译的表达式树会泄漏吗?

    根据我的理解 JIT 代码在程序运行时永远不会从内存中释放 这是否意味着重复调用 Compile 表达式树上会泄漏内存吗 这意味着仅在静态构造函数中编译表达式树或以其他方式缓存它们 这可能不那么简单 正确的 他们可能是GCed Lambda
  • 线程、进程和 Application.Exit()

    我的应用程序由主消息循环 GUI 和线程 Task Factory 组成 在线程中我调用一些第三方应用程序var p new Process 但是当我调用Application Exit 在消息循环中 我可以看到在线程中启动的进程仍在内存中
  • 是否有比 lex/flex 更好(更现代)的工具来生成 C++ 分词器?

    我最近将源文件解析添加到现有工具中 该工具从复杂的命令行参数生成输出文件 命令行参数变得如此复杂 以至于我们开始允许它们作为一个文件提供 该文件被解析为一个非常大的命令行 但语法仍然很尴尬 因此我添加了使用更合理的语法解析源文件的功能 我使
  • 更改窗口的内容 (WPF)

    我创建了一个简单的 WPF 应用程序 它有两个 Windows 用户在第一个窗口中填写一些信息 然后单击 确定 这会将他们带到第二个窗口 这工作正常 但我试图将两个窗口合并到一个窗口中 这样只是内容发生了变化 我设法找到了这个更改窗口内容时
  • .NET 选项将视频文件流式传输为网络摄像头图像

    我有兴趣开发一个应用程序 它允许我从 xml 构建视频列表 包含视频标题 持续时间等 并将该列表作为我的网络摄像头流播放 这意味着 如果我要访问 ustream tv 或在实时通讯软件上激活我的网络摄像头 我的视频播放列表将注册为我的活动网
  • 检查 url 是否指向文件或页面

    我们需要以下内容 如果文件确实是文件 则从 URL 下载该文件 否则 如果它是一个页面 则什么也不做 举个简单的例子 我有以下命令来下载文件 My Computer Network DownloadFile http www wired c
  • 将日期参数传递给对 MVC 操作的 ajax 调用的安全方法

    我有一个 MVC 操作 它的参数之一是DateTime如果我通过 17 07 2012 它会抛出一个异常 指出参数为空但不能有空值 但如果我通过01 07 2012它被解析为Jan 07 2012 我将日期传递给 ajax 调用DD MM
  • 作为字符串的动态属性名称

    使用 DocumentDB 创建新文档时 我想设置属性名称动态地 目前我设置SomeProperty 像这样 await client CreateDocumentAsync dbs db colls x new SomeProperty
  • 已过时 - OpenCV 的错误模式

    我正在使用 OpenCV 1 进行一些图像处理 并且对 cvSetErrMode 函数 它是 CxCore 的一部分 感到困惑 OpenCV 具有三种错误模式 叶 调用错误处理程序后 程序终止 Parent 程序没有终止 但错误处理程序被调
  • 如何在内存中存储分子?

    我想将分子存储在内存中 这些可以是简单的分子 Methane CH4 C H bond length 108 7 pm H H angle 109 degrees But also more complex molecules like p
  • 在Linux中使用C/C++获取机器序列号和CPU ID

    在Linux系统中如何获取机器序列号和CPU ID 示例代码受到高度赞赏 Here http lxr linux no linux v2 6 39 arch x86 include asm processor h L173Linux 内核似
  • 为什么 strtok 会导致分段错误?

    为什么下面的代码给出了Seg 最后一行有问题吗 char m ReadName printf nRead String s n m Writes OK char token token strtok m 如前所述 读取字符串打印没有问题 但

随机推荐