Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

In the following C program, functions f, g, and h are essentially identical, however clang-tidy says that parameter p can be pointer-to-const in g and h (but not in f). My understanding is that p can't be pointer-to-const in any of them. Is that a false positive?

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);
}

Output from 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 

Tried with clang-tidy versions 10 and 11.

The following may be related: https://bugs.llvm.org/show_bug.cgi?id=41393

like image 749
Wolfram Rösler Avatar asked Nov 06 '22 04:11

Wolfram Rösler


1 Answers

The tool is bugged. The intention of this warning is to likely to enforce "const-correctness", something that only matters when the pointer is actually de-referenced inside the function. You don't de-reference the pointers.

But more importantly, the C language requires this for simple assignment of pointers (6.5.1.6.1), emphasis mine:

  • 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;

Making the pointer parameter const would turn s.p = p; and similar into constraint violations - invalid C. The rules of initialization follow the rules of simple assignment too, so the various functions behave identically.

like image 94
Lundin Avatar answered Nov 12 '22 23:11

Lundin