那个函数参数真的可以是指向常量的指针吗?

Wol*_*ler 5 c pointers clang-tidy

在下面的 C 程序中,函数fgh本质上是相同的,但是 clang-tidy 说参数p可以是指向常量的指针 in gand h(但不是 in f)。我的理解是,p它们中的任何一个都不能是指向常量的指针。那是假阳性吗?

struct S { int *p; };

extern void x(struct S *s);

void f(int *p)
{
    struct S s;
    s.p = p;
    x(&s);
}

void g(int *p)
{
    struct S s = { .p = p };
    x(&s);
}

void h(int *p)
{
    struct S s = { p };
    x(&s);
}

int main()
{
    int a = 0;
    f(&a);
    g(&a);
    h(&a);
}
Run Code Online (Sandbox Code Playgroud)

来自 clang-tidy 的输出:

$ clang-tidy --checks=* a.c
Error while trying to load a compilation database:
Could not auto-detect compilation database for file "a.c"
No compilation database found in /home/wolfram or any parent directory
fixed-compilation-database: Error while opening fixed database: No such file or directory
json-compilation-database: Error while opening JSON database: No such file or directory
Running without flags.
2 warnings generated.
/home/wolfram/a.c:14:13: warning: pointer parameter 'p' can be pointer to const [readability-non-const-parameter]
void g(int *p)
            ^
       const 
/home/wolfram/a.c:20:13: warning: pointer parameter 'p' can be pointer to const [readability-non-const-parameter]
void h(int *p)
            ^
       const 
Run Code Online (Sandbox Code Playgroud)

尝试使用 clang-tidy 版本 10 和 11。

以下可能是相关的:https : //bugs.llvm.org/show_bug.cgi?id=41393

Lun*_*din 1

该工具已被窃听。此警告的目的是可能强制执行“常量正确性”,只有当指针在函数内部实际取消引用时才重要。您不会取消引用指针。

但更重要的是,C 语言需要这样来进行简单的指针赋值(6.5.1.6.1),强调我的:

  • 左操作数具有原子、限定或非限定指针类型,并且(考虑左值转换后左操作数将具有的类型)两个操作数都是指向兼容类型的限定或非限定版本的指针,并且左操作数指向的类型具有所有右边指向的类型的限定符;

使指针参数const变成s.p = p;和类似的约束违规-无效C。初始化规则也遵循简单赋值的规则,因此各个函数的行为相同。