1

My main function generates a matrix as an array of values "m", and another array of pointers to the start of rows "M". I want to pass this matrix to a subroutine such that no values can be modified, and such that no row pointers can be modified. I.e., the subroutine must not alter the matrix. As such, I pass a pointer to a constant pointer to a constant value. This works fine. The expected error messages are generated by the example below.

#include<stdio.h>
#include<stdlib.h>

void fun(double const * V, double const * const * M)
{
        V = V; // allowed but pointless
        V[0] = V[0]; // not allowed

        M = M; // allowed but pointless
        M[0] = M[0]; // not allowed
        M[0][0] = M[0][0]; // not allowed
}

int main()
{
        double *V = (double *)malloc(2*sizeof(double));
        double *m = (double *)malloc(4*sizeof(double));
        double **M = (double **)malloc(2*sizeof(double *));

        M[0] = &m[0];
        M[1] = &m[2];

        fun(V,M);

        return 0;
}

Error messages:

test.c: In function ‘fun’:
test.c:7:2: error: assignment of read-only location ‘*V’
test.c:9:2: error: assignment of read-only location ‘*M’
test.c:10:2: error: assignment of read-only location ‘**M’

These are as expected. All good so far.

The problem is that passing a non-constant matrix also generates the following warning. I'm using gcc v4.5 with no options.

test.c: In function ‘main’:
test.c:22:2: warning: passing argument 2 of ‘fun’ from incompatible pointer type
test.c:4:6: note: expected ‘const double * const*’ but argument is of type ‘double **’

Note that passing the vector "V" generates no such warnings.

My question is this: Can I pass a fully mutable matrix to a subroutine in such a way that it cannot be modified, without casting, and without compiler warnings?

user229044
  • 232,980
  • 40
  • 330
  • 338
Bill
  • 468
  • 3
  • 9
  • Ah, this has been asked before. My bad. It doesn't look like this is fixable. http://stackoverflow.com/questions/78125/why-cant-i-convert-char-to-a-const-char-const-in-c?rq=1 – Bill Mar 13 '13 at 13:55

1 Answers1

0

This will help:

void fun(double const * const V, double const * const * const M)
....

The problem you are facing is that double const * is not a const pointer to double, it is a pointer to const double. double const * == const double *.

However there is still one comment: for ordinal types const specifiers are usually not used.

void fun(double const * V, double const * const * M)
.... // this allows to change V or M, but relaxes caller side

Edit: pointers made totally const... So that the data they point to can't be modified.

Valeri Atamaniouk
  • 5,125
  • 2
  • 16
  • 18
  • That doesn't help. `double * const * const` is a const pointer to a const pointer to double. `double * const *` is a pointer to a const pointer to double. Passing either of those would allow fun to modify the values in M. I need a pointer to const double to prevent foo from modifying M. – Bill Mar 19 '13 at 15:28