How to pass multi-dimensional array?

C

Charlie Gordon

James Kuyper said:
pete wrote:
...
int matrix_check(int (*m)[10]) { ... }

I like the pointer notation for the parameter,
because that makes it more obvious what the parameter really is.

If I declared it the way you suggest, the compiler I use most frequently
would insist on reminding me that I should declare 'm' to be const. It
issues no such reminder when I use "int m[][10]", even though that's
functionally equivalent to your declaration. I can't turn off that
reminder without turning off other 'const'-related reminders that I
actually find useful.

It's annoying how stupid things like that can affect your programming
style.

Interesting!

Does it suggest const because it determines the array is not modified in the
body of the function?
It is really unfortunate that a warning like that, while useful in some
circumstances, cannot be controlled on a function basis. It can be a pain
when the function signature is imposed by some external constraint such as
consistency with other functions sharing a common interface.

What compiler are you using?
 
C

Charlie Gordon

pete said:
Keith said:
Charlie Gordon said:
<[email protected]> a écrit dans le message de (e-mail address removed)... [...]
You can do with this simple way to pass it to a function:

int matrix_check(int m[][10])
{
/* chech the 2-dimensional array - m */
return your_return_value;
}

Or even simpler to grasp with:

int matrix_check(int m[10][10]) { ... }

The only subtle trap with this notation
is that sizeof(m) is not the size of the matrix.
[...]

The only other subtle trap is that the first ``10'' is silently
ignored.

int matrix_check(int (*m)[10]) { ... }

I like the pointer notation for the parameter,
because that makes it more obvious what the parameter really is.

The difference between ``int (*m)[10]'' and ``int *m[10]'' is far beyond too
many programmers' understanding of the C syntax. Beginners will find it
much more "understandable" to write ``int m[10][10]''. As long as they do
not attempt to use sizeof, the informative nature of ``10'' will help them.
Too bad this size is completely ignored, to the point where you can "pass"
an array of any length as an argument for this parameter.

What really sucks is the lack of a countof operator that would produce the
number of elements of an array, actual or implied by the ``int m[10][10]''
syntax, while refusing to compile for mere pointer arguments. The
implementation of countof() as a macro in terms of sizeof is still too error
prone.
 
J

James Kuyper

Charlie said:
James Kuyper said:
pete wrote:
...
int matrix_check(int (*m)[10]) { ... }

I like the pointer notation for the parameter,
because that makes it more obvious what the parameter really is.
If I declared it the way you suggest, the compiler I use most frequently
would insist on reminding me that I should declare 'm' to be const. It
issues no such reminder when I use "int m[][10]", even though that's
functionally equivalent to your declaration. I can't turn off that
reminder without turning off other 'const'-related reminders that I
actually find useful.

It's annoying how stupid things like that can affect your programming
style.

Interesting!

Does it suggest const because it determines the array is not modified in the
body of the function?

No, telling me that would be useful, at least for one-dimensional
arrays. This "remark" (it's not labeled as a warning or an error
message, just a remark) is generated because it determines that the
pointer itself is not modified in the body of the function. It is
suggesting that I declare the pointer itself const, not the thing it
points at.
What compiler are you using?

The compiler that comes bundled with SGI's IRIX operating system.
 
C

Charlie Gordon

James Kuyper said:
Charlie said:
James Kuyper said:
pete wrote:
...
int matrix_check(int (*m)[10]) { ... }

I like the pointer notation for the parameter,
because that makes it more obvious what the parameter really is.
If I declared it the way you suggest, the compiler I use most frequently
would insist on reminding me that I should declare 'm' to be const. It
issues no such reminder when I use "int m[][10]", even though that's
functionally equivalent to your declaration. I can't turn off that
reminder without turning off other 'const'-related reminders that I
actually find useful.

It's annoying how stupid things like that can affect your programming
style.

Interesting!

Does it suggest const because it determines the array is not modified in
the body of the function?

No, telling me that would be useful, at least for one-dimensional arrays.
This "remark" (it's not labeled as a warning or an error message, just a
remark) is generated because it determines that the pointer itself is not
modified in the body of the function. It is suggesting that I declare the
pointer itself const, not the thing it points at.

This is so stupid!
Declaring function parameters as const is IMHO useless bloat. It provides
no information to the compiler, and confuses the reader.
Does it complain for all function parameters or just certain types of
pointers?
The compiler that comes bundled with SGI's IRIX operating system.

I'm glad I stay away from those ;-)
 
J

James Kuyper

Charlie said:
"James Kuyper" <[email protected]> a écrit dans le message de
n6FUi.95$a01.79@trnddc06... ....

This is so stupid!
Declaring function parameters as const is IMHO useless bloat. It provides
no information to the compiler, and confuses the reader.
Does it complain for all function parameters or just certain types of
pointers?

All parameters, as far as I can remember; it's been a while since I
compiled with all warnings turned on. I do that at least once before
each major code delivery; but I've been caught up in a flurry of minor
deliveries for the last year or so, so it's been awhile since I've
compiled in that mode.
 
S

santosh

Charlie said:
James Kuyper said:
Charlie said:
"James Kuyper" <[email protected]> a écrit dans le message de
svyUi.368$TO4.343@trnddc07...
pete wrote:
...
int matrix_check(int (*m)[10]) { ... }

I like the pointer notation for the parameter,
because that makes it more obvious what the parameter really is.
If I declared it the way you suggest, the compiler I use most
frequently would insist on reminding me that I should declare 'm'
to be const. It issues no such reminder when I use "int m[][10]",
even though that's functionally equivalent to your declaration. I
can't turn off that reminder without turning off other
'const'-related reminders that I actually find useful.

It's annoying how stupid things like that can affect your
programming style.

Interesting!

Does it suggest const because it determines the array is not
modified in the body of the function?

No, telling me that would be useful, at least for one-dimensional
arrays. This "remark" (it's not labeled as a warning or an error
message, just a remark) is generated because it determines that the
pointer itself is not modified in the body of the function. It is
suggesting that I declare the pointer itself const, not the thing it
points at.

This is so stupid!
Declaring function parameters as const is IMHO useless bloat.

Can you explain why?
 
C

Charlie Gordon

James Kuyper said:
All parameters, as far as I can remember; it's been a while since I
compiled with all warnings turned on. I do that at least once before each
major code delivery; but I've been caught up in a flurry of minor
deliveries for the last year or so, so it's been awhile since I've
compiled in that mode.

make ALL_WARNINGS_ON=1 | grep -v 'parameter should be declared const'
 
C

Charlie Gordon

santosh said:
Charlie said:
James Kuyper said:
Charlie Gordon wrote:
"James Kuyper" <[email protected]> a écrit dans le message de
svyUi.368$TO4.343@trnddc07...
pete wrote:
...
int matrix_check(int (*m)[10]) { ... }

I like the pointer notation for the parameter,
because that makes it more obvious what the parameter really is.
If I declared it the way you suggest, the compiler I use most
frequently would insist on reminding me that I should declare 'm'
to be const. It issues no such reminder when I use "int m[][10]",
even though that's functionally equivalent to your declaration. I
can't turn off that reminder without turning off other
'const'-related reminders that I actually find useful.

It's annoying how stupid things like that can affect your
programming style.

Interesting!

Does it suggest const because it determines the array is not
modified in the body of the function?

No, telling me that would be useful, at least for one-dimensional
arrays. This "remark" (it's not labeled as a warning or an error
message, just a remark) is generated because it determines that the
pointer itself is not modified in the body of the function. It is
suggesting that I declare the pointer itself const, not the thing it
points at.

This is so stupid!
Declaring function parameters as const is IMHO useless bloat.

Can you explain why?

Whether a function parameter is changed during execution of the function
body is usually not important, it depends on what the function does, and how
it is implemented. Sometimes it is appropriate to push a pointer argument,
sometimes it is better to use a local variable. Reading the function will
tell you how the arguments are used, the information the const qualifier
gives you is a minuscule hint, much less useful than say a proper name for
the argument. Sprinkling const qualifiers everywhere actually causes more
obfuscation than good, because of the extra syntax clutter.

Conversely, it is very helpful to const qualify pointer targets: this
conveys useful information, namely the object is not modified by the
function. That is useful for all users of the function. Whether the
function modifies its parameter in its implementation is a useless detail.
 
K

Keith Thompson

Charlie Gordon said:
pete said:
Keith said:
Or even simpler to grasp with:

int matrix_check(int m[10][10]) { ... }

The only subtle trap with this notation
is that sizeof(m) is not the size of the matrix.
[...]

The only other subtle trap is that the first ``10'' is silently
ignored.

int matrix_check(int (*m)[10]) { ... }

I like the pointer notation for the parameter,
because that makes it more obvious what the parameter really is.

The difference between ``int (*m)[10]'' and ``int *m[10]'' is far beyond too
many programmers' understanding of the C syntax. Beginners will find it
much more "understandable" to write ``int m[10][10]''. As long as they do
not attempt to use sizeof, the informative nature of ``10'' will help them.
Too bad this size is completely ignored, to the point where you can "pass"
an array of any length as an argument for this parameter.

Then write ``int m[][10]''. It means exactly the same thing to the
compiler as ``int m[][10]'' (in a parameter declaration), and it
accurately expresses what's really going on.

[...]
 
C

Charlie Gordon

Keith Thompson said:
Charlie Gordon said:
pete said:
Keith Thompson wrote:
Or even simpler to grasp with:

int matrix_check(int m[10][10]) { ... }

The only subtle trap with this notation
is that sizeof(m) is not the size of the matrix.
[...]

The only other subtle trap is that the first ``10'' is silently
ignored.

int matrix_check(int (*m)[10]) { ... }

I like the pointer notation for the parameter,
because that makes it more obvious what the parameter really is.

The difference between ``int (*m)[10]'' and ``int *m[10]'' is far beyond
too
many programmers' understanding of the C syntax. Beginners will find it
much more "understandable" to write ``int m[10][10]''. As long as they
do
not attempt to use sizeof, the informative nature of ``10'' will help
them.
Too bad this size is completely ignored, to the point where you can
"pass"
an array of any length as an argument for this parameter.

Then write ``int m[][10]''. It means exactly the same thing to the
compiler as ``int m[][10]'' (in a parameter declaration), and it
accurately expresses what's really going on.

Sometimes, we really would want the size to be part of the type and make it
obvious with the D syntax:

int matrix_check(int[10][10] m) { ... }
 
K

Keith Thompson

Charlie Gordon said:
Keith Thompson said:
The difference between ``int (*m)[10]'' and ``int *m[10]'' is far
beyond too many programmers' understanding of the C syntax.
Beginners will find it much more "understandable" to write ``int
m[10][10]''. As long as they do not attempt to use sizeof, the
informative nature of ``10'' will help them. Too bad this size is
completely ignored, to the point where you can "pass" an array of
any length as an argument for this parameter.

Then write ``int m[][10]''. It means exactly the same thing to the
compiler as ``int m[][10]'' (in a parameter declaration), and it
accurately expresses what's really going on.

Sometimes, we really would want the size to be part of the type and make it
obvious with the D syntax:

int matrix_check(int[10][10] m) { ... }

Sure, sometimes we want it, but we can't have it in C.

If you really want to pass fixed-size two-dimensional arrays to a
function, consider wrapping them in a structure:

struct matrix_10_10 {
int m[10][10];
};

void func(struct matrix_10_10 *m);

Note that we have to pass it via a pointer explicitly (unless we don't
mind copying the entire matrix on each call), since there's no
implicit struct-to-pointer conversion.

Or you could point to the matrix itself:

void func(int (*m)[10][10]);

In this case, both ``10''s are significant, but the usual
array/pointer confusion may make this unacceptable. A novice C
programmer using this interface is likely to get compiler error
messages, and will be tempted to "fix" them by adding casts. Pointing
to a struct rather than to an array avoids this.

However, I think the need for fixed-size matrices is fairly rare. If
you need to handle 10x10 matrices, you probably need to handle NxN or
MxN matrices. Such code should not be attempted by anyone who hasn't
read section 6 of the comp.lang.c FAQ.
 

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,781
Messages
2,569,615
Members
45,301
Latest member
BuyPureganics

Latest Threads

Top