首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >sal注解(prefast)以强制可变参数的数量

sal注解(prefast)以强制可变参数的数量
EN

Stack Overflow用户
提问于 2015-06-11 11:56:04
回答 2查看 287关注 0票数 3

我有一个可变函数:

代码语言:javascript
复制
print_n_integers(7, 1, 2, 3, 4, 5, 6, 7);

int print_n_integers( unsigned int count, ... )
{
    // use va_start etc.
}

我想使用微软来自sal.h的SAL注释,这样当参数的数量与count不匹配时,Visual Studio编译器就会注意到。我可以通过以下方式将count作为文本强制执行:

代码语言:javascript
复制
int print_n_integers (
    _Literal_ unsigned int count,
    ...
)

Visual Studio至少有一些处理printf()的巧妙之处,但是否有一些简单的参数计数?

EN

回答 2

Stack Overflow用户

发布于 2015-06-11 19:22:24

对于您的问题,我想提出一种不使用静态分析的替代方法。

即使您可以获得用于静态分析的可变参数的计数,您仍然必须为每个调用提供正确的计数。您还必须确保所有参数都是整数(或可以提升为整数)。

处理同源类型列表的一种更自然的、非可变的方法是打印一个数组:

代码语言:javascript
复制
    void print_nint(const int *arr, size_t n);

兼容C99的编译器可以使用compound literals就地创建数组

代码语言:javascript
复制
    print_nint((int[]) {0, 8, 15}, 3);

此语法适合将其自身包装在宏中:

代码语言:javascript
复制
    #define print_int(...)                                  \
        print_nint((int[]){__VA_ARGS__},                    \
            sizeof((int[]) {__VA_ARGS__}) / sizeof(int))

此宏执行计数,您可以在不使用显式参数count的情况下使用它:

代码语言:javascript
复制
    print_int(1, 2, 3.0, rand(), i++, j++);

变量参数的第二个扩展在sizeof中使用,并且不计算。在上面的代码行中,rand()仅被调用一次,ij仅递增一次。在打印之前,浮点参数将转换为int

Visual Studio在2013 RC中引入了复合文字,但旧版本不支持它们。不幸的是,复合文字还会使您的代码无法用于C++编译器。对于这些情况,您可以修改宏以定义一个临时数组:

代码语言:javascript
复制
    #define print_int(...) {                                            \
        int PrintMe_[] = {__VA_ARGS__};                                 \
        print_nint(PrintMe_, sizeof(PrintMe_) / sizeof(*PrintMe_));     \
    }

然而,只有在void上下文中调用函数时,此策略才有效。

如果仅使用宏,则数组及其大小是一致的。但您可以发布底层实现并使用SAL对其进行注释:

代码语言:javascript
复制
    void print_nint(_In_reads_(n) const int *arr, size_t n);

我不提倡不必要地使用宏,但在这种情况下,宏充当模板的角色;它可以减少危险的冗余。

票数 2
EN

Stack Overflow用户

发布于 2015-06-24 04:10:21

不幸的是,SAL中目前还没有针对这种情况的注释。

printf/scanf/scanf_s函数类的支持被硬编码到分析器中,并分别通过_Printf_format_string_ / _Scanf_format_string_ / _Scanf_s_format_string_注释访问(对于特殊情况,可以使用_Printf_format_string_params_ / _Scanf_format_string_params_ / _Scanf_s_format_string_params_)。因此,您唯一的机会就是游说代码分析团队为您的用例添加支持。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30771295

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档