TheMeaningfulEngineer TheMeaningfulEngineer - 2 months ago 7
C Question

Understanding a function declaration when a parameter is const?

Given the following function definition:

void f(int const ** ptr_ptr_a);

how would you understand what the function takes and what it guarantees.

  1. The function takes an
    int **
    as an argument and guarantees no changes to happen explicitly and only to
    inside the function scope.

  2. The function takes an
    int const **
    as the function argument, meaning it is imposing that the passed argument needs to be constant before it entered the function scope.

The motivation comes from trying to understand the warning given by the following example:

void f(int const **ptr_ptr_a){

int main(int argc, char *argv[])
int * ptr_a;
f(& ptr_a); // warning: passing argument 1 of ‘f’ from incompatible pointer type [-Wincompatible-pointer-types]

Assuming definition 1. is correct

The warning is useless and makes us think that the inside of the function makes worries about how the variable behaves outside the function scope.

Assuming definition 2. is correct

Means that the declarations arguments and implying what the qualifiers of the arguments passed to the function during calling should have, in which case I'm confused.

I would kindly ask for an explanation on why is this useful given that only
pass by value
is possible in C.

Answer Source

The declaration int const ** p (or const int ** p) states that p is a pointer to a pointer to an int which is const.

Thus the contract being specified is that f() will not perform an operation such as the following

**ptr_ptr_a = 1;

I.e. it will not write to the referenced int.

It is, however, perfectly free to change the value of ptr_a thus

*ptr_ptr_a = 0;

To remove the warning, ptr_a needs to be declared as int const * ptr_a; or const int * ptr_a; (which is more idiomatic).

Now, is this warning useless? Consider an embedded controller where the pointer size is different for pointers into RAM and ROM/FLASH (and yes, I've worked on those). Your current ptr_a could not address an int which resided in high read-ony memory.