TheMeaningfulEngineer
TheMeaningfulEngineer

Reputation: 16329

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 **ptr_ptr_a 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.

Upvotes: 2

Views: 75

Answers (2)

kdopen
kdopen

Reputation: 8215

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.

Upvotes: 2

Mark Benningfield
Mark Benningfield

Reputation: 2892

Neither definition is correct. When you declare

void f(int const ** ptr_ptr_a);

you're telling the compiler that this function takes a pointer to a pointer to a const int. The warning is the compiler telling you that you are not abiding by your own contract.

Upvotes: 0

Related Questions