加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

如何仅为发布版本内联函数

发布时间:2020-12-16 10:45:38 所属栏目:百科 来源:网络整理
导读:// common.h// This is foo function. It has a body.__inline void foo() { /* something */ }// a.cpp#include "common.h" // for foo function// Call foo// b.cpp#include "common.h" // for foo function// Call foo 我想在我为发布版本构建时内联foo函
// common.h
// This is foo function. It has a body.
__inline void foo() { /* something */ }

// a.cpp
#include "common.h" // for foo function
// Call foo

// b.cpp
#include "common.h" // for foo function
// Call foo

我想在我为发布版本构建时内联foo函数.我不想为Debug构建内联函数.

我试过了,但链接器错误让我烦恼.
在这种情况下,foo函数的主体在common.h头文件中定义.
所以,如果我这样做

//common.h
#if !defined(_DEBUG)
__inline
#endif
void foo() { /* something */ }

它将在DEBUG构建中遇到链接错误.因为两个模块试图包含common.h.
我不知道要解决它.
可能吗?

解决方法

要实现的基本要点是内联关键字(或Microsoft的C语言的__inline扩展 – 因为MSVC不支持C99)本质上是违反一个定义规则的过程.如果你考虑一下 – 这就是它的真实情况,因为编译器没有义务实际执行任何内联.

因此,当您具有内联函数时,您可以在多个模块中定义函数.实际上,您有义务在任何实际使用该功能的模块中定义它.

但是,如果您不将该函数声明为内联函数,则必须确保您只有一个定义(如果实际使用它,则只有一个定义).对于非成员函数(C中的所有函数),有几种方法可以解决这个问题:

>将函数声明为static以更改它与内部的链接(请注意,您可以使用静态内联函数开始).
>在C中,您可以将它们放在匿名命名空间中(其效果类似于声明静态)
>您可以使用预处理器操作来处理此问题.它有点难看,但它有效,而且我已经看到了在野外成功使用的技术.是否值得努力是另一回事 – 你必须自己决定.

基本上,您需要做的是在单独的.c文件中实现该功能,就像您遵循单模块单模块编码标准的传统一样(实际上您也可以这样做)在.c模块中放入几个内联函数 – 但是它们都应该内联或不内联作为一个组来防止事情变得太失控.该函数的实现需要安排能够包含在标题中 – 因此它需要包括警卫,就像任何其他标题一样.然后,当您需要内联函数时,使用预处理器有条件地将实现作为标题的一部分包含在内(因此实现将可用于所有模块),但如果您没有内联,则不要包含它(因此,请遵循一个那种情况下的定义规则):

common.h头:
????// common.h
????#ifndef COMMON_H
????#define COMMON_H

#ifdef RELEASE
#define USE_INLINE
#define INLINE __inline
#else
#define INLINE
#endif

INLINE void foo(void);
#ifdef USE_INLINE
#include "foo.c"
#endif

#endif /* COMMON_H */

foo()的实现:

// foo.c
#ifndef FOO_C
#define FOO_C

#include <stdio.h>
#include "common.h"


INLINE void foo()
{
    printf("foon");
}

#endif /* FOO_C */

一个示例程序:

// main.c
#include<stdio.h>
#include "common.h"

int main()
{
    foo();
    return 0;
}

现在如果你编译发布:

cl /DRELEASE main.c foo.c

foo()将是内联的(或__inline视情况而定).

如果您为非发布编译:

cl  test.c foo.c

你有一个非内联foo().

在任何一种情况下,编译器和链接器都很满意.

总而言之,我有点喜欢将INLINE重新定义为静态以进行调试的建议.

但是,最终我不确定我是否真正看到了这一点 – 现代调试器能够逐步执行内联函数,如果禁用优化,调试器可能不会内联函数调用.因此,您也可以在内联函数中设置断点,并使其在非优化构建中正常工作.

我不确定你究竟是什么样的最终目标.在调试/非优化版本中将函数保留为内联有什么缺点?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读