如何在C99多文件项目中声明内联函数?

发布于 2024-10-20 22:29:58 字数 332 浏览 1 评论 0原文

我想在一个项目中定义一个内联函数,用c99编译。我该怎么做呢? 当我在头文件中声明该函数并在 .c 文件中给出详细信息时,其他文件无法识别该定义。当我将显式函数放入头文件中时,我遇到了一个问题,因为使用它的所有 .o 文件都有定义的副本,因此链接器给我一个“多重定义”错误。

我想做的是:

header.h
inline void func()
{
    do things...
}


lib1.c
#include "header.h"
...

lib2.c
#include "header.h"

使用同时使用 lib1.o 和 lib2.o 的实用程序

I want to define an inline function in a project, compiled with c99. How can I do it?
When I declare the function in a header file and give the detail in a .c file, the definition isn't recognized by other files. When I put the explicit function in a header file, I have a problem because all .o files who use it have a copy of the definition, so the linker gives me a "multiple definition" error.

What I am trying to do is something like:

header.h
inline void func()
{
    do things...
}


lib1.c
#include "header.h"
...

lib2.c
#include "header.h"

with a utility which uses both lib1.o and lib2.o

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一抹苦笑 2024-10-27 22:29:58

不幸的是,并非所有编译器在这一点上都完全符合 C99,即使他们声称自己会这样做。

执行此操作的一种一致方法是

// header file. an inline definition alone is
// not supposed to generate an external symbol
inline void toto(void) {
  // do something
}

// in one .c file, force the creation of an
// external symbol
extern inline void toto(void);

较新版本的 gcc,例如,可以很好地工作。

您可以通过定义类似

#ifdef PRETENDER
# define inlDec static
# define inlIns static
#else
# define inlDec 
# define inlIns extern
#endif
// header file. an inline declaration alone is
// not supposed to generate an external symbol
inlDec inline void toto(void) {
  // do something
}

// in one .c file, force the creation of an
// external symbol
inlIns inline void toto(void);

Edit:

的编译器(通常是选项 -std=c99),我知道

  • gcc (版本 >= 4.3 IIRC) 实现
    正确的 inline 模型
  • pcc 也是正确的
  • ggc 4.3 需要一个特殊选项
    实施正确的模型,
    否则他们使用自己的模型
    这会导致多个定义的
    如果你不小心的话,符号
  • icc 只会在每个单元中发出符号
    如果你不特别注意的话。但
    这些符号是“弱”符号,所以
    它们不会产生冲突。他们
    只是炸掉你的代码。
  • opencc,AFAIR,遵循旧的 gcc 特定模型
  • clang 根本不发出 inline 函数的符号,除非您有 extern 声明您在一个编译单元中使用函数指针。
  • tcc 只是忽略 inline 关键字

Unfortunately not all compilers are completely complying to C99 in that point even if they claim that they'd be.

An conforming way to do this is

// header file. an inline definition alone is
// not supposed to generate an external symbol
inline void toto(void) {
  // do something
}

// in one .c file, force the creation of an
// external symbol
extern inline void toto(void);

Newer versions of gcc, e.g, will work fine with that.

You may get away with it for other compilers (pretenders) by defining something like

#ifdef PRETENDER
# define inlDec static
# define inlIns static
#else
# define inlDec 
# define inlIns extern
#endif
// header file. an inline declaration alone is
// not supposed to generate an external symbol
inlDec inline void toto(void) {
  // do something
}

// in one .c file, force the creation of an
// external symbol
inlIns inline void toto(void);

Edit:

compilers with C99 support (usually option -std=c99) that I know of

  • gcc (versions >= 4.3 IIRC) implements
    the correct inline model
  • pcc is also correct
  • ggc < 4.3 needs a special option to
    implement the correct model,
    otherwise they use their own model
    that results in multiple defined
    symbols if you are not careful
  • icc just emits symbols in every unit
    if you don't take special care. But
    these symbols are "weak" symbols, so
    they don't generate a conflict. They
    just blow up your code.
  • opencc, AFAIR, follows the old gcc specific model
  • clang doesn't emit symbols for inline functions at all, unless you have an extern declaration and you use the function pointer in one compilation unit.
  • tcc just ignores the inline keyword
拥抱没勇气 2024-10-27 22:29:58

如果单独使用,在 C99 中 inline 要求函数定义在与使用它相同的翻译单元中(因此,如果在 lib1.c 中使用它,则必须在 lib1.c 中定义它) )。

您还可以将方法声明为静态内联(并将定义放在两个源文件之间共享的头文件中)。这避免了多重定义问题,并允许编译器在使用该文件的所有翻译单元中内联该文件(如果您只在一个翻译单元中声明该函数,则可能无法做到这一点)。

请参阅:http://www.greenend.org.uk/rjk/2003 /03/inline.html

If used by itself, in C99 inline requires that the function be defined in the same translation unit as it's being used (so, if you use it in lib1.c, it must be defined in lib1.c).

You can also declare a method as static inline (and put the definition in a header file shared between two source files). This avoids the multiple-definition issue, and lets the compiler inline the file across all the translation units where it's used (which it may or may not be able to do if you just declare the function in one translation unit).

See: http://www.greenend.org.uk/rjk/2003/03/inline.html

顾北清歌寒 2024-10-27 22:29:58

我认为在头文件中定义和声明函数时不需要使用内联字,编译器通常默认将其视为内联字,除非它太长,在这种情况下它会足够聪明地处理它作为正常功能。

我认为多重定义可能是由于头文件中缺少 Include Guard 造成的。

你应该在标题中使用类似这样的内容:

#ifndef HEADERNAME_H
#define HEADERNAME_H

void func()
{
    // do things...
}

#endif

I think you don't need to use the inline word when you are defining and declaring the function inside the Header file, the compiler usually takes it as inline by default unless it's too long, in which case it will be smart enough to treat it as a normal function.

I think the multiple definition may be caused by the lack of a Include Guard in the Header file.

You should use something like this in the header:

#ifndef HEADERNAME_H
#define HEADERNAME_H

void func()
{
    // do things...
}

#endif
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文