首页 > 解决方案 > 如何告诉链接器/编译器包含看似“死”的代码

问题描述

我已经编写了一个 C 程序,并且正在使用 GCC(用于 arm MCU)进行编译。我有一个函数可以将 void 指针的地址更改为指向另一个 void,依此类推。问题是链接器/编译器认为代码未使用并丢弃它。我已经尝试过 属性(( used )) 但这没有用。

空白和代码位于与 main.h/c 不同的 .h/.c 文件中,但包含在 main.c 中

代码:

void q2_h(void (*ptr)(uint8_t), uint8_t a) {
    if (a == 3) {
        ptr = (void*) q3_h;
    } else {
        ptr = (void*) q22_h;
    }
}

定义:

void q2_h(void (*ptr)(uint8_t), uint8_t a)__attribute__((used));

输入指针:

void (*ptr)(void*,uint8_t);

这并不完全正确,因为缺少 (uint8_t) 但我不确定语法。

所以如果你对如何解决有任何想法

标签: cpointersarm

解决方案


问题:

  • 该代码更改了一个局部变量,而不是调用代码中的函数指针。所以它不是“看似死了”,而是真的死了。与其摆弄属性,不如听听你的编译器试图告诉你什么。

  • 在处理函数指针时总是使用typedef,它会使错误更加明显。

  • 您不能将函数指针强制转换为 void 指针,反之亦然。void*只是对象指针的通用指针类型。您根本不需要强制转换,或者您的代码正在尝试可疑的无效指针转换,这将是一个错误。

更正后的代码可能类似于:

typedef void func_t (uint8_t);

void q2_h(func_t** ptr, uint8_t a) {
    if (a == 3) {
        *ptr = q3_h;
    } else {
        *ptr = q22_h;
    }
}

推荐阅读