构建时的链接器符号算术计算错误的结果

Posted

技术标签:

【中文标题】构建时的链接器符号算术计算错误的结果【英文标题】:Linker symbol arithmetic at build time computes wrong result 【发布时间】:2019-06-24 08:40:21 【问题描述】:

我正在将 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。 【参考方案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,
;

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

结果:

【讨论】:

谢谢。我检查了您的示例,但它在我的系统上不起作用(结果再次为零)。一定是哪里出了问题…… 当然——正如我所写的——这个例子来自真实的项目。一切正常。

以上是关于构建时的链接器符号算术计算错误的结果的主要内容,如果未能解决你的问题,请参考以下文章

通过函数指针使用内部函数时的链接器错误

Firebase CocoaPods 出现重复符号链接器错误

使用 yaml-cpp 0.5 DLL 时的链接器错误

链接器错误:ld:未找到架构 x86_64 的符号

使用静态成员时的链接器错误

我将如何处理此链接器错误?