这是内联函数的有效用法吗?

时间:2016-10-27 08:45:12

标签: c++ function macros inline

我们说我有这个代码(不要介意SecondsToMinutes和MinutesToHours是彼此的副本)

inline float SecondsToMinutes(float seconds)
{
    return seconds / 60.0;
}
inline float MinutesToHours(float minutes)
{
    return minutes / 60.0;
}
inline float HoursToDays(float minutes)
{
    return minutes / 24.0;
}
inline float SeconndsToHours(float seconds)
{
    return MinutesToHours(SecondsToMinutes(seconds));
}
inline float MinutesToDays(float minutes)
{
    return HoursToDays(MinutesToHours(minutes));
}
inline float SeconndsDays(float seconds)
{
    return MinutesToDays(SecondsToMinutes(seconds));
}

这是内联的有效用法吗?是否有意义?这是好习惯吗?毕竟,如果我没记错的话,内联意味着函数调用被函数体替换,所以

return MinutesToDays(SecondsToMinutes(seconds))

应该相当于

return seconds / 60.0 / 60.0 / 24.0

右?

或者为此使用宏更好吗?

#define EXCHANGE_SEC_MIN(x) (x / 60.0)
#define EXCHANGE_MIN_H(x) (x / 60.0)
#define EXCHANGE_H_D(x) (x / 24.0)
#define EXCHANGE_SEC_H(x) (EXCHANGE_MIN_H(EXCHANGE_SEC_MIN(x)))
#define EXCHANGE_MIN_D(x) (EXCHANGE_H_D(EXCHANGE_MIN_H(x)))
#define EXCHANGE_SEC_D(x) (EXCHANGE_MIN_D(EXCHANGE_SEC_MIN(x)))

哪一种更好的做法?或者两者都不是?我喜欢别人的分数。

4 个答案:

答案 0 :(得分:7)

  

这是内联的有效用法吗?是否有意义?这个好吗   实践?毕竟,如果我没记错,内联意味着功能   调用被函数体替换,所以

当然可以。你让它更清晰,总是好的。

return seconds / 60.0 / 60.0 / 24.0

是的,结果如何。或者应该。 inline只是一个提示,编译可能会另有决定。但对于这样的一个班轮,编译器会内联它。

宏?为什么?如果可以使用函数完成,为什么要使用宏?

答案 1 :(得分:6)

  

这是内联的有效用法吗?它有意义吗?

嗯,是的,但没有。

此时它并没有伤害任何东西,但也没有做你认为它做的事情。

excellent post about inline deft_code中正确地说:

  

据说inline向编译器暗示你认为   功能应该内联。这在1998年可能是真的,但是a   十年后编译器不需要这样的提示。更不用说人类了   在优化代码方面通常是错误的,因此大多数编译器都是如此   不要忽视提示'。

所以,如果你这样做,它不会伤害任何人,但你的编译器听取你的提示的几率几乎为0.如果它认为适合内联代码,它本身就会这样做。

inline现在主要用于链接器,因为它允许多个编译单元中的多个定义。

如果您想确保您的代码尽可能快,并且您可以访问C ++ 11,则应使用constexpr

constexpr float SecondsToMinutes(float seconds)
{
    return seconds / 60.0;
}
//etc..

答案 2 :(得分:3)

inline 意味着函数调用被函数体替换。至少它并没有意味着在过去的十五年里:优化者现在已经超越了开发人员的订单,并且无论你是否指定inline都会执行内联。

inline实际上意味着"此函数可能被定义多次,并且链接器应该对其进行排序并在最后保留最多单个定义。我负责确保所有定义都相同"

如果你真的,真的想要自己实施内联(在调用者中实际插入函数体),你必须使用特定于编译器的扩展,例如为__attribute__((always_inline))

当在标题中定义函数时,通常需要inline,因为此标题最终将包含在多个翻译单元中,因此定义将被复制。因此,假设您的代码位于标题内,这可以很好地使用inline

答案 3 :(得分:0)

假设您的内联函数的定义在使用时对编译器可见(例如,它们位于每个编译单元中需要#include的头文件中),那么您的使用是有效的。

但是,inline只是对编译器的一个提示。标准允许编译器忽略该提示,而不是内联函数。编译器不内联函数的标准高度依赖于编译器。

宏是一种替代方案,但还有其他问题......包括他们不尊重程序范围,并且很容易编写宏 - 故意或意外 - 导致行为与人们预期的不同。因此,内联函数通常被认为是可取的。