我试图强制使用visual c ++编译器来内联特定的函数。我知道inline
或__forceinline
只是一个建议。根据{{3}},如果编译器无法内联使用__forceinline
关键字标记的函数,则会生成警告:
如果编译器无法内联用__forceinline声明的函数, 它会产生1级警告。
但我没有得到这样的警告。当我调试我的应用程序时,我发现在反汇编窗口中有一个call <inlined function address>
,即我的函数没有内联。那我怎么检查我的功能是否内联?这是否意味着如果没有生成警告,那么函数被内联并且问题出现在其他地方?
这是我的功能:
__forceinline SecByteBlock aes_generate_iv(size_t blockSize)
{
const int seedSize = 32;
SecByteBlock rngSeed(seedSize);
OS_GenerateRandomBlock(false, rngSeed, rngSeed.size());
RandomPool rngp;
rngp.IncorporateEntropy(rngSeed, rngSeed.size());
SecByteBlock aesIV(blockSize);
rngp.GenerateBlock(aesIV, aesIV.size());
return aesIV;
}
以下情况是VC ++无法内联函数(来自MSDN):
答案 0 :(得分:0)
同一警告有两个版本:
https://msdn.microsoft.com/en-us/library/aa734011(v=vs.60).aspx
编译器警告(1级)C4714
Visual Studio 6.0
&#39;功能&#39; :标记为__forceinline的函数未内联
https://msdn.microsoft.com/en-us/library/a98sb923.aspx
编译器警告(4级)C4714
Visual Studio 2015
功能&#39;功能&#39;标记为__forceinline未内联
因此,要启用警告,例如,在Visual Studio 2015中,您必须默认使用级别4(/ W4)而不是级别3(/ W3)。
以下有关如何消除此类编译器行为的建议。 我在MSVC2015中解决了这些案例:
SomeType SomeType::operator++(int)
/ SomeType SomeType::operator--(int)
std::string
在__forceinline函数template <typename T>
__forceinline T int_log2_floor(T v)
{
ASSERT_GT(v, T(0));
if (1 >= v) return 0;
return T((v >= 2 ? int_log2_floor(v / 2) : 0) + 1); // Warning C4714
}
这里的一个解决方案就是展开递归:
template <typename T>
__forceinline T int_log2_floor(T v)
{
ASSERT_GT(v, T(0));
if (1 >= v) return 0;
T ret = 0;
T i = v;
do {
++ret;
i /= 2;
} while (i >= 2);
return ret;
}
class SomeType
{
__forceinline SomeType operator++(int) // Warning C4714
{
const auto it = *this;
m_it++;
return it;
}
//...
iterator m_it
};
这个对我有用:
class SomeType;
SomeType operator++(SomeType & r, int);
class SomeType
{
friend SomeType operator++(SomeType & r, int);
//...
iterator m_it
};
__forceinline SomeType operator++(SomeType & r, int)
{
const auto it = r;
r.m_it++;
return it;
// You still can write here `const auto it = *this; m_it++; return it`,
// but i hell don't know why this works.
}
这个真的很奇怪,但似乎之间存在某种干扰
__forceinline
- inline
- ed函数之间的std::string
个函数,因为inline
基本上使用第二个函数 - template<typename T>
__forceinline std::string int_to_bin(T i, bool first_bit_is_lowest_bit = false) // Warning C4714
{
std::bitset<sizeof(T) * CHAR_BIT> bs(i);
if (!first_bit_is_lowest_bit) {
return bs.to_string();
}
const std::string bs_str = bs.to_string();
return std::string(bs_str.rbegin(), bs_str.rend());
}
。
inline
由于警告是由按值返回类型触发的,因此此处的解决方案是通过参数返回并通过template<typename T>
__forceinline void int_to_bin_forceinline(std::string & ret, T i, bool first_bit_is_lowest_bit = false)
{
std::bitset<sizeof(T) * CHAR_BIT> bs(i);
if (!first_bit_is_lowest_bit) {
ret = bs.to_string();
return;
}
const std::string bs_str = bs.to_string();
ret = std::string(bs_str.rbegin(), bs_str.rend());
return;
}
template<typename T>
inline std::string int_to_bin(T i, bool first_bit_is_lowest_bit = false)
{
std::string res;
int_to_bin_forceinline(res, i, first_bit_is_lowest_bit);
return res;
}
内联:
inline
毋庸置疑,所有3个版本都可以通过__forceinline
关键字用法而不是doesRelativeDateFormatting
来解决。