By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,402 Members | 1,117 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,402 IT Pros & Developers. It's quick & easy.

Question about a prototype involving "const"

P: n/a
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[i] = malloc(n * sizeof *a[i]);

a[0][0] = 1.0;

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

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

--
Rouben Rostamian
Feb 19 '06 #1
Share this Question
Share on Google+
2 Replies


P: n/a
In article <dt**********@pc18.math.umbc.edu>
Rouben Rostamian <ro****@pc18.math.umbc.edu> wrote:
... 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>.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Feb 19 '06 #2

P: n/a
Rouben Rostamian wrote:
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[i] = malloc(n * sizeof *a[i]);
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
Feb 19 '06 #3

This discussion thread is closed

Replies have been disabled for this discussion.