删除 Splint 中的空警告

发布于 2024-08-11 11:25:32 字数 859 浏览 1 评论 0原文

我一直在用我最近编写的 C 程序尝试 Splint 并尝试理解并删除它给出的警告。一个我理解但无法理解如何删除它的代码片段来自以下代码片段:

static MyType_t *findById(const int id)
{
    int i;

    for (i = 0; i < MY_ARR_SIZE; i++) {
            if (my_arr[i].id == NOT_SET) {
                    /* Items are sorted so that items with 
                    NOT_SET as ID are at the end of the array */
                    break;
            }
            if (my_arr[i].id == id) {
                    return &(my_arr[i]);
            }
    }
    return NULL; 
}

Splint 不高兴该函数可以返回 NULL,但在这种情况下它非常有意义。

我尝试使用 /@nullwhenfalse@/ 但似乎只有在函数返回 true/false 时才有效,并且还尝试更改代码以使用 retVal 并尝试了 /@null@< /em>/ 和 /@relnull@/ 位于声明前面,但这些没有任何作用。

(顺便说一句,这张桌子只有 20 个大 atm,所以使用聪明的搜索算法是没有意义的。)

I have been trying out Splint with a C program I recently wrote and trying to understand and remove the warnings it gives. One I understand but can't understand how to remove it comes from the following code snippet:

static MyType_t *findById(const int id)
{
    int i;

    for (i = 0; i < MY_ARR_SIZE; i++) {
            if (my_arr[i].id == NOT_SET) {
                    /* Items are sorted so that items with 
                    NOT_SET as ID are at the end of the array */
                    break;
            }
            if (my_arr[i].id == id) {
                    return &(my_arr[i]);
            }
    }
    return NULL; 
}

Splint isn't happy that the function can return NULL, but in this case it makes perfect sense.

I tried using /@nullwhenfalse@/ but it seems to only work if the function returns true/false and also tried to change the code to use a retVal and tried both /@null@/ and /@relnull@/ in front of the declaration, but these did nothing.

(Just as a side-note, the table is only 20 big atm, so no point in using a clever search algorithm.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

最笨的告白 2024-08-18 11:25:32

您应该仔细检查声明前面的 /*@null@*/ 的使用。

在示例的以下可编译版本中,它确实删除了警告(使用夹板 3.1.2):

typedef struct { int id; } MyType_t;
#define NOT_SET -1
#define MY_ARR_SIZE 20
static MyType_t my_arr[MY_ARR_SIZE];

/*@null@*/ static MyType_t *findById(const int id)
{
    int i;
    for (i = 0; i < MY_ARR_SIZE; i++) {
            if (my_arr[i].id == NOT_SET) {
                    /* Items are sorted so that items with 
                    NOT_SET as ID are at the end of the array */
                    break;
            }
            if (my_arr[i].id == id) {
                    return &(my_arr[i]);
            }
    }
    return NULL;
}

int main() {
    (void)findById(10);
    return 0;
}

如果您仍然有类似的警告,是否可能与代码的另一部分有关?

You should double check the use of /*@null@*/ in front of the declaration.

In the following compilable version of your example, it does remove the warning (using splint 3.1.2):

typedef struct { int id; } MyType_t;
#define NOT_SET -1
#define MY_ARR_SIZE 20
static MyType_t my_arr[MY_ARR_SIZE];

/*@null@*/ static MyType_t *findById(const int id)
{
    int i;
    for (i = 0; i < MY_ARR_SIZE; i++) {
            if (my_arr[i].id == NOT_SET) {
                    /* Items are sorted so that items with 
                    NOT_SET as ID are at the end of the array */
                    break;
            }
            if (my_arr[i].id == id) {
                    return &(my_arr[i]);
            }
    }
    return NULL;
}

int main() {
    (void)findById(10);
    return 0;
}

If you still have a similar warning, could it be about another part of your code ?

顾挽 2024-08-18 11:25:32

splint -nullret 将消除该警告(全局),这可能是也可能不是您想要做的事情。在某些情况下,除非您确信返回 NULL 的类型是正确的,否则您可能想要警告。

我测试了杰罗姆的示例,它确实消除了该特定函数的警告。

splint -nullret will squash that warning (globally) which may or may not be what you want to do. In some cases, unless you are sure having a type return NULL is correct, you probably want the warning.

I tested Jerome's example, and it did hush the warning for that particular function.

少女情怀诗 2024-08-18 11:25:32

无论您做什么,我强烈建议不要将夹板代码直接嵌入到源代码中,而是将该功能包装在宏中。

例如,在 Parrot 项目中,我有这些宏

#  define ARGIN(x)                    /*@in@*/ /*@notnull@*/
#  define ARGIN_NULLOK(x)             /*@in@*/ /*@null@*/
    /* The pointer target must be completely defined before being passed */
    /* to the function. */

#  define ARGOUT(x)                   /*@out@*/ /*@notnull@*/
#  define ARGOUT_NULLOK(x)            /*@out@*/ /*@null@*/
    /* The pointer target will be defined by the function */

然后使用宏,以便我们可以使用:

void copy_string( ARGOUT(char *target), ARGIN(const char *source ) ) ...

如果我们想更改 ARGIN() 参数的处理方式,我们可以更改它的一处。我们还可以支持多个工具或编译器的多种符号。

Whatever you do, I would strongly suggest not embedding splint codes directly into the source, but instead wrap that functionality in a macro.

For example, over on the Parrot project, I have these macros

#  define ARGIN(x)                    /*@in@*/ /*@notnull@*/
#  define ARGIN_NULLOK(x)             /*@in@*/ /*@null@*/
    /* The pointer target must be completely defined before being passed */
    /* to the function. */

#  define ARGOUT(x)                   /*@out@*/ /*@notnull@*/
#  define ARGOUT_NULLOK(x)            /*@out@*/ /*@null@*/
    /* The pointer target will be defined by the function */

And then macros are used so we can use:

void copy_string( ARGOUT(char *target), ARGIN(const char *source ) ) ...

If we want to change how ARGIN() arguments are handled, we change it one place. We can also support multiple notations for multiple tools or compilers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文