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

Can that function parameter really be pointer-to-const?

在下面的 C 程序中,函数 fgh 本质上是相同的,但是 clang-tidy 说参数 p 可以是指针- to-const 在 gh 中(但在 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);
}

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 

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

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

工具有问题。此警告的目的是可能强制执行“const-correctness”,这仅在指针在函数内部实际取消引用时才重要。您不取消对指针的引用。

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

  • the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) both operands are pointers to qualified or unqualified versions of compatible types, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;

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