【发布时间】:2020-03-06 04:00:58
【问题描述】:
我已经通过链接https://devblogs.microsoft.com/oldnewthing/20131114-00/?p=2663 了解使用 va_list 的潜在陷阱
下面来自同一链接的代码段指定不要以显示的方式使用 va_list,因为 va_list 不能直接复制。
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_copy 似乎没有做任何事情
#define va_copy(destination, source) ((destination) = (source))
我的问题是在 windows 中使用 va_copy 是否安全 va_list ?如果是,为什么,如果不是,那么前进的方向是什么?
【问题讨论】:
-
在我看来这个问题更多的是关于 FormatMessage 所以也许会在标题中提到这一点
-
既然你已经用 C 和 C++ 标记了它,有必要指出 C 要求你使用
va_copy()来复制参数列表(不需要宏除此以外)。此外,在从函数返回(或重用复制的列表等)之前,您必须在复制的列表上使用va_end()。见 C11§7.16 Variable arguments<stdarg.h>。 -
va_copy可以从 Windows 的stdarg.h获得,这意味着它可以工作;否则他们不会费心去定义它。 -
@jamesdlin C++ 也需要这些东西(它在这个主题上遵循 ISO C)
-
@M.M 这个回复是给@Jonathan Leffler 的吗?我不确定它是否与 C++ 的 C 一致性有关。与完全不提供
va_copy相比,提供一个损坏的va_copy实现实际上并不符合标准(无论哪种标准)......
标签: c++ c c++11 variadic-functions variadic-macros