两个c文件之间的全局内联函数



以下是我之前问过的这个问题。我想知道如何在全局范围内定义inline函数。

我想在test.h中声明inline函数,在main.c中<strong]定义>它,然后从test.c调用

main.c和test.c都是#include "test.h"(有关代码示例,请单击上面的链接)。

这基本上是用户可以启用/禁用的某种回调函数。并且只有一个文件应该定义函数

我知道inline只是对编译器的一个建议,它在现代CPU上没有太大区别,但这是针对8位微控制器的,真的需要它

编辑:

我在test.c中有一个函数,它调用这个内联函数。我只想用main.c中定义的函数体来替换调用。我希望这是有意义的。

大多数8位微控制器代码都是用接近C89的语言编写的(通常有扩展,例如内联汇编),而inline直到C99才正式成为C的一部分。因此,首先要确定编译的标准(如果有的话),如果inline是一个扩展(即不是C99内联),请参阅编译器手册。在编程领域,编译器手册优先于C标准。

根据C99,如果main.ctest.c都需要调用同一个函数,并且需要将其标记为inline,那么我认为必须在标头中定义它,因为inline函数不能跨越转换单元(即".c"文件)。

例如:

测试.h:

static inline int add(int a, int b) { return a + b; }

main.c:

#include "test.h"
void main(void)
{
   int x = add(10,15);
}

测试.c:

#include "test.h"
int test(void)
{
   int x = add(10,15);
   return x;
}

编辑:请参阅此处以更好地解释C99 inline的用法:如何在C99多文件项目中声明内联函数?

然而,这可能会导致生成的对象代码出现各种奇怪的行为。例如,我看到专业MCU mfg的编译器(有意不命名)在给定的翻译单元中为inline函数#included生成目标代码,而不是内联它们。该文件包含在多个位置,并包含许多函数,因此这导致整个代码库中ROM的总体使用量大幅增加,因为链接器也无法删除死代码(参见gcc--gc-sections),并且由于函数从未实际内联,因此未能提高性能,尽管从技术上讲,内联的正确使用是。

我们对这个特定问题的解决方案是将所有函数转换为宏(这为inline提供了性能优势),但另一种方法是从声明中删除inline,并将定义移动到单个.c文件中。

TL;DR:如果对MCU使用inline,1)请参阅编译器手册,2)密切关注生成的目标代码。

假设你说的是真的,有问题的函数是一个回调,那么你就不能内联回调。这是没有意义的,回调调用通常通过函数指针进行,我认为你不能指望编译器证明它的值是恒定的(并且在编译时是已知的),这样它就可以用内联代码代替调用。

您可以在C中使用inline关键字,但如果您使用GNU GCC编译器,则需要内联函数也是static函数。因此,您只能在同一个源文件中使用这些函数。如果你想声明一个在某个头文件中定义的全局内联函数,并在包含该头文件的源文件中使用它,你可以使用GNUGCC的always_inline属性,如下所示:

static inline __attribute__((always_inline)) int foo(int a)
{
  return a+2;
}

不要忘记在同一个头文件中声明内联函数的主体。

它的工作方式正是这样,你只有一个函数的定义,比如说它是函数int add(int x, int y);,然后你在main.c 中定义它

main.c

int add(int x, int y)
{
    return x + y;
}

如果你想在另一个c文件中使用它,你只需要这个

测试.c

int add(int x, int y); /* just a declaration, a function prototype */
int addWrapper(int x, int y)
{
    return add(x, y);
}

像这样编译

gcc -Wall -Werror main.c test.c -o some_output_file_name

并且链接器将负责查找函数定义。

如果函数未在任何已编译的文件中定义,则

Undefined reference to `int add(int x, int y);' in ...

将发出错误。

如果你想强迫编译器插入函数体,然后自己插入函数体。使用预处理器宏

页眉.h

#define add(x,y) ((x) + (y))

然后

#include "header.h"
int addWrapper(int x, int y)
{
    return add(x, y);
}

将用CCD_ 27代替CCD_。

如果函数返回void,那么一个很好的技巧就是使用这个

#define inlinedFunction(parameters) 
    do {                            
        /* function body here */    
    } while (0)

您应该在宏定义的每一行的末尾添加一个连续反斜杠。

相关内容

  • 没有找到相关文章

最新更新