constexpr 与 constexpr 内联与定义 - 优化 C 和 C++ 中的通用实用函数

问题描述 投票:0回答:1

我有一个简单的函数,我在操作代码中为

C
编译,在测试中为
C++
编译。由于我将在代码中广泛使用此函数,因此我想在实用程序文件中声明它并使其尽可能高效。

让我们考虑一个计算两个

uint64_t
值之间的绝对差的示例函数。

这里有三个选项:

选项1:

constexpr uint64_t diff(uint64_t a, uint64_t b)
{
    return a > b ? a - b : b - a;
}

在 C++ 中,该函数将在编译时求值并隐式内联。

在C中,

constexpr
将被忽略,仅表示函数的返回值为
constexpr

选项2:

constexpr inline uint64_t diff(uint64_t a, uint64_t b)
{
    return a > b ? a - b : b - a;
}

在 C++ 中,该函数将在编译时求值并隐式内联。

inline
关键字是多余的。

在C中,

constexpr
会被忽略,仅暗示函数的返回值为
constexpr
,并且有提示编译器切换函数与函数体。

选项3:

#define DIFF(a, b) ((a) > (b) ? ((a) - (b)) : ((b) - (a)))

在 C++ 中,它可以工作,但使用

constexpr
函数可以增加类型安全性。

在 C 中,它可以工作,并且可能是最有效的方法,就像在内联函数中一样,编译器可能会忽略内联。

哪个选择更好,为什么?还有第四种选择吗?

请记住,我需要为

c
c++
选择最佳选择。

c++ c optimization inline constexpr
1个回答
0
投票

理想的选择是你还没有提到的:

constexpr static inline uint64_t diff(uint64_t a, uint64_t b)
{
    return a > b ? a - b : b - a;
}

C 语言需要

static inline
的原因是
inline
在 C 中的工作方式不同。它仅仅让您提供内联定义,但如果该函数实际上并未内联(例如在调试版本中),您会得到一个链接器错误而不在某个地方声明它
extern inline

static inline
避免了这个问题,并允许您通过内部链接定义标头中的所有内容。 虽然很脏,但是有用。

在 C++ 中,

static inline
是合法的,尽管有点多余。
constexpr
已经使函数成为内联函数,我们不需要使用
static
来解决此问题,因此您也可以编写:

#ifdef __cplusplus
#define C_STATIC_INLINE
#else
#define C_STATIC_INLINE static inline
#endif
#define

constexpr C_STATIC_INLINE uint64_t diff(uint64_t a, uint64_t b)
{
    return a > b ? a - b : b - a;
}
© www.soinside.com 2019 - 2024. All rights reserved.