数组和结构体可以以不同的方式初始化吗?

2024-04-05

我的问题可能看起来很奇怪 事实上,这是上下文:

我目前在切换时遇到一个奇怪的问题 -关于我正在从事的项目- 核心从pullinino到CV32(也发生了一些其他变化,例如关于crt0,如一些数据内存重置)。

这是一个(真实的)例子,说明了一个非常简单的 main 所发生的情况 (我无法提供startup/crt0文件编辑:我在帖子后面部分给出了它).

#include <string.h>
#include <inttypes.h>
#include <stdio.h>

typedef struct
{
    uintptr_t addr;
    uint32_t foo;  
} some_struct_t;

static uint32_t text_in_data[8] = {0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x55555555, 0x66666666, 0x77777777, 0x88888888};
uint32_t text_in_data2[8] = {0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x55555555, 0x66666666, 0x77777777, 0x88888888};

some_struct_t text_in = {(uintptr_t)text_in_data, 8};
static some_struct_t text_in2 = {(uintptr_t)text_in_data, 8};

int main(void)
{
    some_struct_t text_in3 = {(uintptr_t)text_in_data, 8};
    static some_struct_t text_in4 = {(uintptr_t)text_in_data, 8};
    static some_struct_t text_in5 = {(uintptr_t)text_in_data2, 8};

    printf("text_in_data[]: ");
    for (uint8_t i=0;i<8;i++)
    {
        printf("0x%08x, ",(unsigned int)text_in_data[i]);
    }
    printf("\n");
    printf("text_in_data2[]: ");
    for (uint8_t i=0;i<8;i++)
    {
        printf("0x%08x, ",(unsigned int)text_in_data2[i]);
    }
    printf("\n");
    printf("text_in1.addr 0x%08x -- @text_in_data 0x%08x\n",(unsigned int)text_in.addr,(unsigned int)text_in_data);
    printf("text_in2.addr 0x%08x -- @text_in_data 0x%08x\n",(unsigned int)text_in2.addr,(unsigned int)text_in_data);
    printf("text_in3.addr 0x%08x -- @text_in_data 0x%08x\n",(unsigned int)text_in3.addr,(unsigned int)text_in_data);
    printf("text_in4.addr 0x%08x -- @text_in_data 0x%08x\n",(unsigned int)text_in4.addr,(unsigned int)text_in_data);
    printf("text_in_data2.addr 0x%08x -- @text_in_data2 0x%08x\n",(unsigned int)text_in5.addr,(unsigned int)text_in_data2);

    text_in = (some_struct_t){(uintptr_t)text_in_data, 8};
    text_in2 = (some_struct_t){(uintptr_t)text_in_data, 8};
    text_in3 = (some_struct_t){(uintptr_t)text_in_data, 8};
    text_in4 = (some_struct_t){(uintptr_t)text_in_data, 8};
    text_in5 = (some_struct_t){(uintptr_t)text_in_data2, 8};

    printf("text_in1.addr 0x%08x -- @text_in_data 0x%08x\n",(unsigned int)text_in.addr,(unsigned int)text_in_data);
    printf("text_in2.addr 0x%08x -- @text_in_data 0x%08x\n",(unsigned int)text_in2.addr,(unsigned int)text_in_data);
    printf("text_in3.addr 0x%08x -- @text_in_data 0x%08x\n",(unsigned int)text_in3.addr,(unsigned int)text_in_data);
    printf("text_in4.addr 0x%08x -- @text_in_data 0x%08x\n",(unsigned int)text_in4.addr,(unsigned int)text_in_data);
    printf("text_in_data2.addr 0x%08x -- @text_in_data2 0x%08x\n",(unsigned int)text_in5.addr,(unsigned int)text_in_data2);

    return 0;
}

gives

text_in_data[]: 0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x55555555, 0x66666666, 0x77777777, 0x88888888, 
text_in_data2[]: 0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x55555555, 0x66666666, 0x77777777, 0x88888888, 
text_in1.addr 0x00000000 -- @text_in_data 0x00140478
text_in2.addr 0x00000000 -- @text_in_data 0x00140478
text_in3.addr 0x00140478 -- @text_in_data 0x00140478
text_in4.addr 0x00000000 -- @text_in_data 0x00140478
text_in_data2.addr 0x00000000 -- @text_in_data2 0x00140498
text_in1.addr 0x00140478 -- @text_in_data 0x00140478
text_in2.addr 0x00140478 -- @text_in_data 0x00140478
text_in3.addr 0x00140478 -- @text_in_data 0x00140478
text_in4.addr 0x00140478 -- @text_in_data 0x00140478
text_in_data2.addr 0x00140498 -- @text_in_data2 0x00140498

第一个问题是text_in<x>.addr当使用静态存储定义时,不会被初始化,但本地定义会被初始化。

有很多事情可以解释这种行为,例如我们正在重置 crt0 中的数据内存。

编辑:重置不是由于数据内存重置造成的,测试固件代码没有发生这种重置,它已通过帖子后面提供的修复程序进行了纠正

但我无法理解的是text_in_data<x>初始化得很好,但是text_in<x> is not.

它们应该共享相同的部分(=以相同的方式存储在相同的位置),不是吗?

它们之间的唯一区别是有些是数组,有些是结构......


我查看了原始pulpinino之间的差异crt0.riscv.S https://github.com/sifive/picolibc/blob/master/libgloss/riscv/crt0.S以及我们正在使用的那个。

没有任何差异可以解释这种行为,但我发现了这一点patch https://sourceware.org/pipermail/newlib/2021/018247.html.

确实,最新的crt0.S https://raw.githubusercontent.com/pulp-platform/pulpino/master/sw/ref/crt0.riscv.S包含更多更正

But by JUST更换la a0, _edata by la a0, _bss_start, that 使代码片段工作.

但无法真正解释为什么会有这种行为。因为使用edata在 bss 重置循环中,我想我明白最后一个edata未对齐的单词也被重置 (. = ALIGN(4);之间_edata and _bss_start)

BUT这并不能解释为什么在结构和数组之间修复之前有如此不同的行为......

这是链接器脚本的一部分

    .data : {
        . = ALIGN(4);
        sdata  =  .;
        _sdata  =  .;
        *(.data);
        *(.data.*)
        edata  =  .;
        _edata  =  .;
    } > dataram

    .bss :
    {
        . = ALIGN(4);
        _bss_start = .;
        *(.bss)
        *(.bss.*)
        *(.sbss)
        *(.sbss.*)
        *(COMMON)
        _bss_end = .;
    } > dataram

    /* ensure there is enough room for stack */
    .stack (NOLOAD): {
        . = ALIGN(4);
        . = . + _min_stack ;
        . = ALIGN(4);
        stack = . ;
        _stack = . ;
    } > stack

    .stab  0 (NOLOAD) :
    {
        [ .stab ]
    }

    .stabstr  0 (NOLOAD) :
    {
        [ .stabstr ]
    }

    .bss :
    {
        . = ALIGN(4);
        _end = .;
    } > dataram

做了之后riscv32-corev-elf-objdump -d *.elf,两个报告之间的唯一区别是 bss 重置循环的开始地址。 但地址变为0x1405bc(用于工作),以及0x14059c(对于不工作的人)。

0x14059c是地址text_in对于那些二进制文件。


您是否可以解释为什么数组和结构之间存在这种差异以及为什么此补丁纠正了该问题?


None

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

数组和结构体可以以不同的方式初始化吗? 的相关文章

  • 如何将这段 javascript 代码重写为 C++11?

    这是我在 Javascript Definitive Guide 中看到的 javascript 闭包代码 我想把它写成C 11 var uniqueID1 function var id 0 return function return
  • Visual Studios 2015 中的“恢复 NuGet 包”没有执行任何操作

    我将解决方案从 SVN 拉入 Visual Studios 2015 代码中的一些 使用 引用出现错误 因此我尝试在右键单击 解决方案 中的解决方案时运行 恢复 NuGet 包 选项探索者 这没有任何作用 我必须手动进入 nuget 管理器
  • 无法使用c#更改视频捕获分辨率

    我正在尝试使用 C 中的 DirectShowNet 更改默认网络摄像头分辨率 据我所知 我需要通过调用 windows win32 api dll 中内置的 VideoInfoHeader 类来更改它以进行 avi 捕获 我有来自 Dir
  • 如何在 ASP.NET MVC 中将 XML 文件发送到客户端

    在 ASP NET MVC 中 我有一个数据库表 我想在某个视图页面上有一个按钮 如果某个用户单击该按钮 我的应用程序将生成包含数据库中所有行的 XML 文件 然后 应将包含 XML 的文件发送到客户端 以便用户看到下载弹出窗口 同样 我希
  • 信号与信号2

    我的应用程序可能会受益于使用 boost 的信号库之一而不是本土解决方案 该应用程序是多线程的 但执行信号处理的部分是单线程的 如果多线程不是问题 是否有任何理由更喜欢 Boost Signals2 而不是 Boost Signal Boo
  • Winform DatagridView 数字列排序

    我只使用一个简单的 DataGridView 来保存一堆数据 有趣的是 我在特定列中有小数 但是当按小数列排序时 它的排序是错误的 例如 起始顺序可能是 0 56 3 45 500 89 20078 90 1 56 100 29 2 39
  • 预编译头和 Visual Studio

    有没有办法设置 Visual Studio 解决方案参数 以便它只创建预编译头而不构建整个解决方案 具体来说 它是一个巨大的 C 解决方案 本身有许多项目 谢谢 仅选择 pch 创建者源文件 通常是 stdafx cpp 然后编译该文件 C
  • 如何从不同的线程访问控件?

    如何从创建控件的线程以外的线程访问控件 避免跨线程错误 这是我的示例代码 private void Form1 Load object sender EventArgs e Thread t new Thread foo t Start p
  • 在 .NET Core 中从 HttpResponseMessage 转换为 IActionResult

    我正在将之前在 NET Framework 中编写的一些代码移植到 NET Core 我有这样的事情 HttpResponseMessage result await client SendAync request if result St
  • asp.net core http 如果没有内容类型标头,则删除 `FromBody` 忽略

    我在 http 中使用 bodyDELETE要求 我知道目前删除主体是非标准的 但是允许的 使用时出现问题HttpClient它不允许删除请求的正文 我知道我可以使用SendAsync 但我宁愿让我的 API 更加灵活 我希望这个机构是可选
  • 模板与非模板类,跨编译器的不同行为

    我在一些应用程序中使用编译时计数器 它确实很有用 昨天我想用 gcc 编译一个程序 我之前使用的是 msvc 并且计数器的行为在模板类中发生了变化 它在模板类中不再工作 过于简化的代码 Maximum value the counter c
  • 从 C# 调用时无法识别 Powershell 命令

    这是这个的延续Question https stackoverflow com questions 66280000 powershell object returns null 66280138 noredirect 1 comment1
  • 如何禁用基于 ValidationRule 类的按钮?

    如何禁用基于 ValidationRule 类的 WPF 按钮 下面的代码可以很好地突出显示 TextBox
  • 使用 cmake 将两种解决方案合二为一

    我有两个单独的 Visual Studio 2013 解决方案 我想将它们迁移到一个解决方案中 因为第一个解决方案 使用 Qt 充当第二个解决方案的 GUI 最后 我希望有一个结构如下的单一解决方案 Solution All Build P
  • 从具有相同属性的另一个对象创建对象

    我有一个 C 对象 可以说有 20 个属性 它是数据契约的一部分 我还有另一个具有类似属性的业务实体 我想从响应对象中填充该实体 除了将一个对象的每个属性分配给另一个对象的相应属性之外 还有其他方法可以做到这一点吗 是的 看看自动映射器 h
  • 在 C# 命令行应用程序中包含并执行 EXE

    所以我找到了一个很棒的小 EXE 命令行应用程序 我们将其称为 program exe 它输出一些我想用 C 操作的数据 我想知道是否有一种方法可以将program exe 打包 到我的Visual Studio项目文件中 这样我就可以将编
  • 调试错误:在 vc++ 项目中使用 COM 时发生 所需的运行时?

    我为我的工作创建了一个 COM 组件 我也注册了该组件 在我的系统上 我有两个虚拟机工作站 在我的第一个工作站中 它运行良好 在我的第二个工作站中 它显示一个包含消息的错误框该程序需要一段时间并以不寻常的方式关闭 请联系应用程序管理员 我认
  • 使用任务的经典永无止境的线程循环?

    给出了一个非常常见的线程场景 宣言 private Thread thread private bool isRunning false Start thread new Thread gt NeverEndingProc thread S
  • C# PasswordDeriveBytes:似乎 Salt 并不重要

    可能我误解了什么 以下代码通过 CryptDeriveKey 使用两种不同的盐生成两个相等的密钥 这是控制台结果 盐1 21 3e 18 a3 9a 8b 5f gt 键 da 89 ea 3d 91 08 20 98 20 e9 dc 4
  • 强制函数调用的顺序?

    假设我有一个抽象基类 并且我想要一个必须由派生类实现的纯虚方法 但我想确保派生方法以特定顺序调用函数 我可以做什么来强制执行它 I E base class virtual void doABC 0 virtual void A 0 vir

随机推荐

  • 更改 TensorBoard 中的图像滑块步骤

    TensorBoard 1 1 0 的图像历史 我想更精确地设置滑块的位置 在带有 7 的黑色图像顶部 以便能够选择任何步骤 现在我只能选择例如在步骤2050或2810之间 这可能吗 也许源代码中的某个位置对 10 常数进行了硬编码 我在那
  • php 邮件功能无法使用

    当我尝试在本地主机上使用 php 邮件功能发送邮件时 出现以下错误 可能是什么问题 我什至尝试更改 php ini 文件并给 smtp 主机值提供我的服务提供商值及其仍在努力工作 警告 mail function mail 无法连接到 lo
  • 使用滑动窗口函数处理向量的 MATLAB 函数,返回向量响应矩阵

    假设向量v尺寸的1 x n和功能fun接受一个长度向量L并返回一个大小向量p x 1 是否有一个 MATLAB 函数可以接受向量v 处理每个长度的滑动窗口L使用函数 fun 并返回大小的矩阵p x n or p x n L 我知道这可以通过
  • 对 JSON 编码的字段使用 MySQL LIKE 运算符

    我一直在尝试使用此查询获取表行 SELECT FROM table WHERE field LIKE u0435 u0442 u043e u0442 字段本身 Field u0435 u0442 u043e u0442 u0442 u043
  • 如何创建具有包结构的jar文件?

    我有一个文件夹结构 com cdy ws a class files com cdy ws b class files com cdy ws c class files 当我运行以下命令 jar cvf asd jar class 时 它会
  • abort() 不是 VS2010 中的 __declspec(noreturn)

    在我的 VS2010 副本中 stdlib h 包含 第 353 355 行 CRTIMP declspec noreturn void cdecl exit In int Code CRTIMP declspec noreturn voi
  • 如何撤消 Angular 2 Cli ng-eject?

    我刚刚执行了ng eject命令 但现在我需要恢复它 并继续使用ng命令 是否可以 我将不胜感激任何帮助 At https github com angular angular cli blob master packages 40angu
  • 如何获取给定字体文件的字体系列的名称?

    我有一组文件名不可预测的字体文件 因此我无法从文件名中推断出真正的 字体系列 名称 因此 我需要读取字体元数据以提取真正的 字体系列 名称 以便渲染此字体文件 我使用的是 C NET 4 0 WinForms 我见过这个功能GetFontI
  • 如何将日期选择器最大日期限制为今天? [复制]

    这个问题在这里已经有答案了 问题就在标题里 我有两个日期选择器 从和到 我想将日期选择器限制为当前日期 我怎么做 提前致谢 使用 maxDate 选项 http jqueryui com demos datepicker option ma
  • 如何处理 Web API 中的可选查询字符串参数

    我正在编写一个 Web API 我希望了解处理可选查询字符串参数的最佳方法是什么 我有一个定义如下的方法 HttpPost public HttpResponseMessage ResetPassword User user var que
  • SQL Server 加权全文搜索

    目前 我有一个表 可以在 4 个字段 名字 姓氏 中间名和别名 上搜索 我目前有一个包含稳定搜索行并且它有效 不太好 但它有效 现在我想让名字的权重更高 中间名的权重更低 我找到了命令ISABOUT但如果我必须通过文字而不是专栏来完成它 那
  • 无法在基于 JHipster 的 Web 应用程序中运行从 Gradle BootRepackage 生成的 war

    我正在尝试与java jar生成的war文件 gradlew Pprod bootRepackage The bootRepackage任务成功结束 当我看着project root build libs 文件夹中 war 和 war or
  • 在 postgresql 中搜索数组中的元素而不使用循环

    我正在编写一个查询来搜索数组中的元素 使用 for 循环搜索效率不高 因为我的数组有很多元素 因此 查询需要花费大量时间来执行 那么任何人都可以说如何在没有 for 循环的情况下搜索数组中的元素 这应该更快 我必须获取搜索索引 谢谢 卡西卡
  • 如何修改内核DTB文件

    Summary 我目前正在为定制板编译 Linux 内核 内核 模块和 DTB 以及一些定制驱动程序 有时 我会编译内核并意识到 DTB 文件中的兼容性字符串不是自定义驱动程序正在寻找的内容 现在 我可以解决此问题的唯一方法是修改 DTS
  • 我想我需要一个简单的规则引擎? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 在 UINavigationController 上推送多个视图控制器时出现内存问题

    我正在为 iPad 制作一本互动书 并且正在使用UINavigationController实现页面与下一页之间的导航 当用户翻页时 下一页被推送到导航堆栈的顶部 我现在已经进入应用程序的 15 页 当我尝试从第 14 页转到第 15 页时
  • 如何重命名 Oracle 过程

    有没有一种方法可以重命名 Oracle 过程 而不必删除并重新创建该过程 不幸的是 没有等效的ALTER TABLE RENAMETO 用于 PL SQL 对象 所以恐怕您将不得不放弃该过程并使用新名称重新创建它 除非使用 SYNONYM
  • RxJava + 改造,获取列表并为每个项目添加额外信息

    我正在玩 RXJava 在 Android 中进行改造 我正在努力完成以下任务 我需要定期轮询一个给我 Observable gt 的调用 从这里我可以做到 一旦我得到这个列表 我想在每个交付中迭代并调用另一个方法来给我预计到达时间 所以只
  • 将“this”传递给 onclick 事件[重复]

    这个问题在这里已经有答案了 可能的重复 当前元素作为其事件函数参数 https stackoverflow com questions 4268085 the current element as its event function pa
  • 数组和结构体可以以不同的方式初始化吗?

    我的问题可能看起来很奇怪 事实上 这是上下文 我目前在切换时遇到一个奇怪的问题 关于我正在从事的项目 核心从pullinino到CV32 也发生了一些其他变化 例如关于crt0 如一些数据内存重置 这是一个 真实的 例子 说明了一个非常简单