首页 > 解决方案 > 为什么 PC-Lint 抱怨重新声明(错误 18)?

问题描述

请注意,以下代码毫无意义,我只是想重现我在更复杂的代码库中看到的错误。显然,我不会创建具有全局范围的变量来将其传递给仅在该变量所在的一个文件中使用的函数。

我正在运行 PC-Lint 9.00L。

在以下示例中,PC-Lint 抱怨重新声明:

example2.c 18 错误 18: Symbol'testFunction(const struct AnotherExample_t *)' redeclared (Arg. no. 1:qualification) 与第 21 行冲突,文件 example.h,模块 example1.c

这是代码:

例子.h

#ifndef EXAMPLE_H
#define EXAMPLE_H

#include <stdint.h>

typedef struct
{
    volatile uint8_t item1;
    volatile uint8_t item2;
} Example_t;

typedef struct
{
    Example_t * p_items;
    uint8_t something;
    uint16_t somethingElse;
} AnotherExample_t;

extern AnotherExample_t g_externalVariable;

extern void testFunction (AnotherExample_t const * const p_example);  //line 21
    
#endif

例子1.c

#include "example.h"
#include <stdio.h>

int main(void)
{
    g_externalVariable.something = 5;
    
    (void)printf("%d", g_externalVariable.something);
    
    testFunction(&g_externalVariable);
    return 0;
}

例子2.c

#include "example.h"
#include <stdio.h>

static Example_t p = 
{
    .item1 = 0,
    .item2 = 1,
};

AnotherExample_t g_externalVariable =
{
    .p_items = &p,
    .something = 2,
    .somethingElse = 3,
};

void testFunction (AnotherExample_t const * const p_example)
{  // Line referenced in lint (line 18)
    (void)printf("%d", (int)p_example->somethingElse);
}

为什么 lint 会抛出此错误?

我尝试过的事情

我注意到,当我删除const AnotherExample_t投诉消失的声明时。IE -

extern void testFunction (AnotherExample_t * const p_example);  //example.h

void testFunction (AnotherExample_t * const p_example)  //example2.c
{
    ...
}

我还尝试从 example1.c 进行调用,以查看是否有任何改变:

testFunction((AnotherExample_t const * const)&g_externalVariable);

这并没有改变什么。

在这两种情况下,我都会收到一条 Info 818 消息:

example2.c 20 信息 818:指针参数“p_example”(第 17 行)可以声明为指向 const

最少的可重现代码

这也会导致同样的错误。

例子.h

#ifndef EXAMPLE_H
#define EXAMPLE_H

extern void testFunction (const char * const p_example);
    
#endif

例子1.c

#include "example.h"
#include <stdio.h>

int main(void)
{
    char testValue = 'c';
    char * p_testValue = &testValue;
    
    testFunction(p_testValue);
    
    return 0;
}

例子2.c

#include "example.h"
#include <stdio.h>

void testFunction (const char * const p_example)
{
    (void)printf("%c", p_example);
}

标签: cstatic-analysislintpc-lint

解决方案


这既不是 PC-Lint 的错误,也不是我的代码中的错误。编译器库中的一些关键字重新定义导致 PC-Lint 在其预处理步骤中去除了一些关键字(例如constvolatile)。

最终结果是,当我添加#include <stdio.h>我的定义时testFunction,它的限定符将被剥离,const并且它不再与我的标题中的声明匹配。

我在我的文件中添加了以下选项,co-XXXX.lnt错误就消失了。

+dconst=const
+dvolatile=volatile

特别感谢 Gimpel 的工作人员,尽管这个版本的 PC-Lint 不再受支持,但他们愿意与我一起解决这个问题。

更新

不幸的是,我还没有时间去追查这些库中哪些地方const正在volatile被重新定义,但我发现了一个比仅仅在 lint 编译器选项文件中重新定义这些关键字更好的解决方法。利用-scavengePC-Lint 中的选项,然后运行该选项通过预处理器创建的 .c 文件,会创建一个头文件,该头文件定义了编译器的内置宏以供 PC-Lint 使用。这是我使用的过程。

lint-nt -i"/path/to/my/libraries" -scavenge(*.h) > interim.c

然后,我从 Code Composer Studio 运行了我的代码的标准构建,以验证哪些选项正在使用 cl430 编译器运行。之后,我使用相同的选项通过编译器运行 interim.c - 唯一的例外是我使用该-ppo选项仅通过预处理器运行它,将生成的文件保存为 interim.lnt。

此时,PC-Lint 手册说要运行:lint -scavenge(clean,interim.lnt). 在我的情况下,似乎只清除了所有数据的文件,所以我跳过了这一步。但是,检查在此步骤之前创建的 interim.lnt 文件显示我的所有宏都是在此文件中创建的。我将它重命名为 lint_header.h 并将以下几行添加到我的 co-MSP430.lnt 文件的开头:

-header(lint_header.h)
+libh(lint_header.h)

我不再使用 +d 选项,const并且volatile现在可以更准确地表示我的库文件应该如何与 PC-Lint 一起使用。我也不再有重新声明错误。


推荐阅读