C++ 在windows上使用va_copy安全吗
我已经使用va_列表浏览了潜在陷阱的链接 同一链接的下面代码段指定不以所示方式使用va_列表,因为va_列表不可直接复制C++ 在windows上使用va_copy安全吗,c++,c,c++11,variadic-functions,variadic-macros,C++,C,C++11,Variadic Functions,Variadic Macros,我已经使用va_列表浏览了潜在陷阱的链接 同一链接的下面代码段指定不以所示方式使用va_列表,因为va_列表不可直接复制 BOOL FormatWithFallbackLanguage( DWORD dwMessageId, PCTSTR pszBuffer, SIZE_T cchBuffer, va_list ap) { va_list apOriginal = ap; // Format from the user's preferred language. DWORD cch
BOOL FormatWithFallbackLanguage(
DWORD dwMessageId, PCTSTR pszBuffer, SIZE_T cchBuffer, va_list ap)
{
va_list apOriginal = ap;
// Format from the user's preferred language.
DWORD cchResult = FormatMessage(
FORMAT_MESSAGE_FROM_HMODULE,
g_hinst, dwMessageId, g_preferredLangId,
pszBuffer, cchBuffer, &ap);
// If that didn't work, then use the fallback language.
if (cchResult == 0) {
cchResult = FormatMessage(
FORMAT_MESSAGE_FROM_HMODULE,
g_hinst, dwMessageId, g_fallbackLangId,
pszBuffer, cchBuffer, &apOriginal);
}
return cchResult != 0;
}
链接中的文章建议在上述编码场景中使用va_copy。然而,在windows上,在头文件stdarg.h中,va_副本似乎没有任何作用
#define va_copy(destination, source) ((destination) = (source))
我的问题是,在windows for va_列表中使用va_copy是否安全?如果是,为什么,如果不是,那么前进的方向是什么? < P>如果你使用的编译器符合ISO C++,那么<代码> VAYIONS < /Cord>是安全的(这是重言式)。p> FormatMessage函数可能会破坏列表,但我认为不会。如果是这样的话,那么链接文章中关于重新启动列表的另一个建议也不会起作用 你试过建议的代码了吗?va_副本的正确使用应为:
va_list ap2;
va_copy(ap2, ap);
DWORD cchResult = FormatMessage(
FORMAT_MESSAGE_FROM_HMODULE,
g_hinst, dwMessageId, g_preferredLangId,
pszBuffer, cchBuffer, &ap);
if (cchResult == 0)
cchResult = FormatMessage(
FORMAT_MESSAGE_FROM_HMODULE,
g_hinst, dwMessageId, g_fallbackLangId,
pszBuffer, cchBuffer, &ap2);
va_end(ap2);
你不应该往里面看香肠是怎么做的。:-) 好的,现在你看了。您已经看到,Windows并不是那些复杂的调用约定需要在
va_列表中分配内存的平台之一。事实证明,您实际上不需要使用va_copy
而不是简单的赋值,而且va_end
实际上什么都不做。那很糟糕。你不该看的。现在你必须忘掉这一切
因为明天一切都可能改变。一个新的库或编译器优化逻辑的更新,或者谁知道是什么,突然需要va_copy
,va_end
可以防止内存泄漏,而你的内疚突然变成了一个危险的错误
标准规定,您必须使用va_copy
复制va_列表
。标准规定,对于每个初始化的va_列表
,您必须调用va_end
。你必须这样做。因为你不可能知道在你的平台上不需要它,而不去窥探你不该去的地方
标准图书馆不必遵守这些规则。它可以完全了解自己的平台和内部结构,因为它只需要在自己的环境中工作。如果有什么变化,维护标准库的好心人会意识到这一点,并且他们会确保新版本在他们的平台上与新版本的编译器一起工作
这就是交易:实现将保证,如果你按规则行事,事情就会成功。这些规则的存在是为了让实现者能够处理他们平台的特性,并且让编译器能够挤出尽可能多的优化周期
有时候,偷工减料和违反规则似乎不会有什么坏处,至少现在和现在不会。但不要屈服于这种诱惑。因为如果你这样做了,你早就在代码中留下了一个定时炸弹。我觉得这个问题更多的是关于FATATEMAGE,所以也许提到在TITLE中你已经用C和C++来标记这个,这就说明C需要你使用<代码> VAYCONTION()/<代码>复制参数列表。(否则不需要宏)。此外,在从函数返回(或重用复制的列表等)之前,必须在复制的列表上使用va_end()
参见C11。“代码> VAX拷贝<代码>可从Windows的代码> STARDG.H./CODE >表示它是工作的;否则它们不会打扰定义。@ JAMESDLIN C++也需要这些东西(它在这个主题上服从ISO C)“M.M”是针对Jonathan Leffler的回答吗?我不确定它是否与C++的一致性有关。而不是根本不发货va_copy
。。实际上,到目前为止,我在windows上还没有遇到任何问题,但上面的文章对它的用法产生了疑问。另外,stdarg.h中定义va_copy的方式增加了混乱。因此,我想知道对windows来说,使用va_list和va_copy是否是一种安全的方式?@J.Snow操作系统没有任何关系问题是,编译器是否符合C++标准,我不能很明显地回答,但是如果你发现它没有,你可以把一个bug报告文件可能会有点混乱,但是为了增加更多,我使用Visual Studio 2017来编译Windows上的代码。还有什么可以检查的吗?Y编译器符合C++标准?@ J.Sunt并不是真的;如果它看起来有效,那么我就不会担心它。