【问题标题】:Inline function with assert creates an undefined reference? [duplicate]带有断言的内联函数创建一个未定义的引用? [复制]
【发布时间】:2018-05-19 19:43:01
【问题描述】:

divide.h

#pragma once

#include <assert.h>

inline int divide(int a, int b)
{
        assert(b != 0);
        return a / b;
}

main.c

#include <divide.h>

int main(void)
{
        divide(10, 2);
        return 0;
}

由于assert,我无法编译以下内容。如果我删除断言,一切正常。

$ gcc --version
gcc (GCC) 8.1.0
$ gcc main.c
main.c:(.text+0xf): undefined reference to `divide'
$ gcc main.c -O3 # Compilation with optimization works as asserts are removed.

divide 的定义放在.c 文件中时,一切正常。但是,由于函数被声明为inline,以下是否也可以工作?

【问题讨论】:

  • 为什么头文件中有可执行代码?编译器没有有义务使函数内联 - 这不是宏。
  • @WeatherVane 但是,如果 inline 函数不完全驻留在头文件中,您就无法真正将其包含在内,对吗?
  • @JohnBoyer 如果你想强制编译器使用内联函数,你需要声明它static inline
  • 测试中有趣的事情,当您从函数中删除内联标识符时,代码编译完美。另外,编译器应该只是将文本放在头文件中#included的位置,所以头文件中的可执行代码对编译器应该没问题,(我自己不推荐)。

标签: c


【解决方案1】:

C99 标准在 6.7.4“函数说明符”中对内联函数进行了说明:

内联定义提供了外部定义的替代方案,翻译人员可以使用它来实现对同一翻译单元中函数的任何调用。未指定对函数的调用是使用内联定义还是外部定义。

因此,实现可以选择不内联函数调用,在这种情况下,需要对函数进行外部定义。我猜由于断言是一个调试工具,GCC 不希望内联具有活动断言的函数来帮助调试。

【讨论】:

  • 如果不保证所有函数都内联,C 中的仅标头库如何工作?
  • @JohnBoyer 他们按照标准使用static inline
猜你喜欢
  • 2021-10-28
  • 2013-10-04
  • 1970-01-01
  • 2011-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-07
相关资源
最近更新 更多