【问题标题】:Linker symbol arithmetic at build time computes wrong result构建时的链接器符号算术计算错误的结果
【发布时间】:2023-03-20 16:12:01
【问题描述】:

我正在将 GCC 用于 STM32 微控制器应用程序,但遇到了一个奇怪的现象。我在闪存中有一个常量值表,其中包含来自链接器符号的地址。现在我想添加另一个值,其中包含来自两个链接器符号的计算(在构建时),但它似乎不起作用。

它看起来像这样:

extern uint32_t _ls1;   // Linker symbol 1          
extern uint32_t _ls2;   // Linker symbol 2      
const volatile uint32_t table[4] =
{
    (uint32_t)(&_ls1),                    // 1. Correct value 
    (uint32_t)(&_ls2),                    // 2. Correct value 
    (uint32_t)(&_ls1) + 1,                // 3. Correct value 
    (uint32_t)(&_ls1) + (uint32_t)(&_ls2) // 4. Wrong value, always 0
}

表中的前三个值完全正确。
每当我在计算中放入两个(或更多)链接器符号时,结果为 0。没有给出错误或警告。

有任何想法吗?

【问题讨论】:

  • (uint32_t)(&_ls1) + (uint32_t)(&_ls2) 不会溢出吗? &_ls1&_ls2 表达式的值是多少? No error or warning is given. - 你用-Wall -Wextra 编译吗? two Linker symbols - 你能提示这些变量是如何从链接器中导出的吗?您是否尝试使用uint64_tunsigned long long 类型进行计算?你如何检查结果值是否正确?你能创建一个最小的可重现示例MCVE吗?包括整个链接器、main() 函数、包含、编译器等?
  • >不会 (uint32_t)(&_ls1) + (uint32_t)(&_ls2) 溢出吗?没关系,我尝试什么样的计算(加、减、异或等),结果总是0。

标签: gcc linker


【解决方案1】:

您的链接描述文件有问题。

我已经使用我的东西对其进行了测试(我现在正在使用 STM32L476,gcc)

volatile const uint32_t test[] = {
        (uint32_t)&_edata,
        (uint32_t)&_sdata,
        (uint32_t)&_edata + 1,
        (uint32_t)&_edata + 2,
        (uint32_t)&_edata + (uint32_t)&_sdata,
};

(此表只能自动存储,否则无法编译)

结果:

【讨论】:

  • 谢谢。我检查了您的示例,但它在我的系统上不起作用(结果再次为零)。一定是哪里出了问题……
  • 当然——正如我所写的——这个例子来自真实的项目。一切正常。
猜你喜欢
  • 1970-01-01
  • 2012-02-26
  • 1970-01-01
  • 2021-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-13
  • 1970-01-01
相关资源
最近更新 更多