首先,there's no portable way计算va_list
的长度。也许有一种方法可以在Visual C ++的调试(非优化)配置中执行此操作?
具体来说,我有一个可变函数:
void MyVariadic( const char* format, ... )
{
}
(我无法更改签名)并且我想检测format
包含百分比字符并且参数列表为空的情况(这可能意味着有人直接传递了任何字符串来代替{{1} }而不是使用format
),一旦我发现这种情况,我可以%s
或其他。
有没有办法在Visual C ++中调试非优化版本?
答案 0 :(得分:4)
由于您可以使用Visual C ++特定的解决方案,并且如果您的目标是帮助检测不匹配的printf样式格式字符串,请考虑使用SAL Annotations。如果格式字符串和参数不匹配,则在启用代码分析的情况下运行的构建将报告错误。
您想要的注释是_Printf_format_string_
。看看printf
如何在stdio.h
中注释以获取灵感。
请考虑以下代码:
int i = 12;
printf("%d %s", i);
Visual C ++ 2013为我运行代码分析报告
C6063'printf'缺少字符串参数,对应于说明符'2'。
答案 1 :(得分:2)
(来自评论)
问题基本上在MyVariadic(str)
之类的调用中,其中str
仅在运行时知道const char[]
。我们无法更改void MyVariadic(const char*, ...)
的签名,但我们可以添加重载。 void MyVariadic(const char*)
是一个更好的匹配。
从void MyVariadic(const char* str)
起,很难转发到void MyVariadic(const char*, ...)
。通用解决方案是将&MyVariadic
转换为void (*p)(const char*, ...)
,但在此特定情况下,const char*
是类似printf的格式。这意味着我们可以转发到MyVariadic("%s", str)
。
答案 2 :(得分:0)
一种可能的方法是使用可变参数宏(具有硬编码限制):
#define COUNT_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
#define COUNT(...) COUNT_N(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
// Warning: COUNT() return 1 (as COUNT(A)) :-/
#define ARG1(S, ...) S
然后执行以下操作:
#define MyVariadic_And_Check(...) do { \
Check(ARG1(__VA_ARGS__), COUNT(__VA_ARGS__) - 1); \
MyVariadic(__VA_ARGS__); } while(false)
使用Check(const char* format, int count)
检查参数计数的功能
注意:由于MyVariadic至少有const char* format
,COUNT
会给出正确答案。
在C ++ 11中,您可以使用以下内容:
template <typename ... Args>
void MyVariadic_And_Check(const char* format, Args&&...args);
验证计数和类型。