Question about a prototype involving "const"

R

Rouben Rostamian

The main() function in the following code defines an m by n
matrix, assigns value(s) to its elements, then passes the matrix
to function foo().

For whatever it's worth, I have declared foo() so as to make
it treat its first argument as a "read-only" object, that is,
foo() can read but not alter the matrix.

I have a problem, however, with /calling/ foo. If I call
foo as foo(a,m,n), my compiler (gcc) complains about:

try.c:22: warning: passing argument 1 of 'foo' from
incompatible pointer type

I can silence the warning by using a cast:

foo((double const * const *)a, m, n);

I wonder, however, if there is a way to declare foo() to
make the cast unnecessary but at the same time tell it that
its argument is a read-only object.

%---% sample code: try.c %-----------------------------------%
#include <stdlib.h>

void foo(double const * const *a, size_t m, size_t n)
{
a[0] = NULL; /* illegal */
a[0][0] = 4.0; /* illegal */
2.0*a[0][0]; /* legal */
}

int main(void)
{
double **a;
size_t m=3, n=5;
size_t i;

a = malloc(m * sizeof *a);
for (i=0; i<m; i++)
a = malloc(n * sizeof *a);

a[0][0] = 1.0;

foo((double const * const *)a, m, n); /* really want foo(a,m,n); */

return 0;
}
%---% end sample code %--------------------------------------%
 
C

Chris Torek

... I have declared foo() so as to make
it treat its first argument as a "read-only" object, that is,
foo() can read but not alter the matrix.

I have a problem, however, with /calling/ foo. If I call
foo as foo(a,m,n), my compiler (gcc) complains about:

try.c:22: warning: passing argument 1 of 'foo' from
incompatible pointer type

"Const" is effectively broken in C. (It would work in C++.)

See <http://c-faq.com/ansi/constmismatch.html>.
 
F

Flash Gordon

Rouben said:
The main() function in the following code defines an m by n
matrix, assigns value(s) to its elements, then passes the matrix
to function foo().

You should be clear about what you mean by a matrix since that is not
one of the types in the C language. In this case you are constructing it
dynamically as pointers to pointers.
For whatever it's worth, I have declared foo() so as to make
it treat its first argument as a "read-only" object, that is,
foo() can read but not alter the matrix.

I have a problem, however, with /calling/ foo. If I call
foo as foo(a,m,n), my compiler (gcc) complains about:

try.c:22: warning: passing argument 1 of 'foo' from
incompatible pointer type

This is a serious warning.
I can silence the warning by using a cast:

foo((double const * const *)a, m, n);

This is question 11.10 of the comp.lang.c FAQ
http://c-faq.com/ansi/constmismatch.html
I wonder, however, if there is a way to declare foo() to
make the cast unnecessary but at the same time tell it that
its argument is a read-only object.

Any time you put in a cast to shut the compiler up you are doing the
wrong thing. There are times when a cast is needed, but you should only
use a cast because you know it is needed and understand *why* it is
needed. Once you've read question 11.10 ask about anything in the answer
you don't understand and once you understand the reason for a cast you
can cast. However, you have other problems as well...
%---% sample code: try.c %-----------------------------------%
#include <stdlib.h>

void foo(double const * const *a, size_t m, size_t n)
{
a[0] = NULL; /* illegal */
a[0][0] = 4.0; /* illegal */
2.0*a[0][0]; /* legal */

Do you want to make:
a = NULL;
illegal as well? If so you would need another const in there...
}

int main(void)
{
double **a;
size_t m=3, n=5;
size_t i;

a = malloc(m * sizeof *a);

You need to check to see if malloc succeeded (or if you've stripped out
checks to simplify code for posting, state up front that you have done
this).
for (i=0; i<m; i++)
a = malloc(n * sizeof *a);


Again, the check if malloc succeeded.
a[0][0] = 1.0;

foo((double const * const *)a, m, n); /* really want foo(a,m,n); */

This is mentioned near the bottom of question 11.10. The question mostly
talks about assignment, but passing parameters uses the same rules.
return 0;
}
%---% end sample code %--------------------------------------%
--
Flash Gordon
Living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidlines and intro -
http://clc-wiki.net/wiki/Intro_to_clc
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top