C 删除Splint中的空警告

C 删除Splint中的空警告,c,static-analysis,syntax-checking,splint,C,Static Analysis,Syntax Checking,Splint,我一直在试用我最近编写的一个C程序,试图理解并删除它给出的警告。我理解但不理解如何从以下代码段中删除它: 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 wit

我一直在试用我最近编写的一个C程序,试图理解并删除它给出的警告。我理解但不理解如何从以下代码段中删除它:

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; 
}
static MyType\u t*findById(const int id)
{
int i;
对于(i=0;i
Splint对函数可以返回NULL感到不高兴,但在这种情况下,它是非常有意义的

我尝试过使用/@nullwhenfalse@/但它似乎只在函数返回true/false并尝试将代码更改为使用retVal时才起作用,并且在声明前尝试了/@null@/和/@relnull@/两种方法,但这两种方法都没有起作用


(作为旁注,该表只有20个大atm,因此没有必要使用聪明的搜索算法。)

您应该在声明前仔细检查/*@null@*/的使用情况

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

typedef struct{int id;}MyType\t;
#定义NOT_集合-1
#定义我的尺码20
静态MyType_t my_arr[我的大小];
/*@null@*/static MyType\u t*findById(const int id)
{
int i;
对于(i=0;i

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

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


我测试了Jerome的示例,它确实消除了针对该特定函数的警告。

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

例如,在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()参数的处理方式,只需改变一个位置。我们还可以为多个工具或编译器支持多个符号。

我认为您应该a)不要将传递值参数声明为“const”,但这可能是您的风格,b)包括Splint提供的实际诊断输出,“nothappy”有点模糊。嗯,为什么我不应该将其声明为const?我喜欢const,部分原因是它表明函数不会改变值。好的,好的。当我按下提交按钮时,我就意识到了为什么你不喜欢使用const。好的一点,我只是自动添加const到所有的输入参数,而不考虑它是通过值还是通过引用。@解开<代码> const int id < /Cord>参数有助于编译器警告您,如果您意外修改<代码> ID>代码>,这是您可以考虑的(虽然我不使用它)。@Makis的要点是,如果您在添加它时没有考虑它是按值传递还是按引用传递,那么您不会在同一级别添加它。我认为自己在C中做过实验,每次使用类型限定符时都会暂停思考。我不建议“自动”使用它们。是的,这会删除警告,但我不想完全删除它。@Makis:是的,在这种情况下,按照Jerome的建议做会更好,事实上我已经投票支持他的答案。
void copy_string( ARGOUT(char *target), ARGIN(const char *source ) ) ...