Pointer to array of unspecified size

  • Thread starter Christopher Benson-Manica
  • Start date
C

Christopher Benson-Manica

From FAQ 6.13:

int arr[4][5];
int (*a)[]=arr; /* legal, but useless */

printf( "%d\n", a[0][0] ); /* error, bounds of a unspecified */

Are there non-contrived situations where an array of unspecified
bounds is useful?
 
D

Dan Pop

In said:
From FAQ 6.13:

int arr[4][5];
int (*a)[]=arr; /* legal, but useless */

printf( "%d\n", a[0][0] ); /* error, bounds of a unspecified */

The actual error is that you're trying to perform pointer arithmetic
on a pointer to an incomplete type, which is impossible in C.
Are there non-contrived situations where an array of unspecified
bounds is useful?

Plenty of them, mostly in <stdio.h>, <string.h> and <stdlib.h>.

Or, in C89, where you have no VLAs, the only way to use an array defined
in a different module, whose size is not known at compile time:

extern char buff[];
extern size_t buffsize;

OTOH, if you're talking about pointers to arrays of unspecified size,
they're useless because pointer arithmetic doesn't work on them. A
pointer to the first element of an array of unspecified size, which is
the type buff in my above example decays into, is a lot more useful.

Dan
 
K

Kghost

Christopher Benson-Manica said:
From FAQ 6.13:

int arr[4][5];
int (*a)[]=arr; /* legal, but useless */
~~~~~~~~~~~~~~here error cannot convert to int(*)[] from int[][]

maybe int *a[] work better
for( i=0;i<4;i++)
a= &arr[0]
printf( "%d\n", a[0][0] ); /* error, bounds of a unspecified */

Are there non-contrived situations where an array of unspecified
bounds is useful?
 
C

Christopher Benson-Manica

Dan Pop said:
The actual error is that you're trying to perform pointer arithmetic
on a pointer to an incomplete type, which is impossible in C.
Thanks.

Plenty of them, mostly in <stdio.h>, <string.h> and <stdlib.h>.

Can you give me an example of what you're talking about? I glanced
OTOH, if you're talking about pointers to arrays of unspecified size,

Yes.
they're useless because pointer arithmetic doesn't work on them.

I figured as much, which leads me to my real question: If it's
wholly useless, why make it legal syntax? To someone who hasn't read
FAQ 6.13 (I'm sure such people exist), it might seem tempting to
declare (*a)[] and then attempt to use it.
 
C

Christopher Benson-Manica

Dan Pop said:
OTOH, if you're talking about pointers to arrays of unspecified size, [yes]
they're useless because pointer arithmetic doesn't work on them.

It also leads me to ask whether the following C program is
conforming...

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

void myfunc( int (*arr)[] )
{
int (*k)[5]=arr;
int i;

for( i=0 ; i<20 ; i++ )
printf( "%d\n", k[i/5][i%5] );
}

int main( void )
{
int arr[4][5];
int (*k)[]=arr;
int i;

printf( "%p == %p\n", (void *)arr, (void *)k );
for( i=0 ; i<20 ; i++ )
arr[i/5][i%5]=i;

myfunc( k );

return EXIT_SUCCESS;
}
 
D

Dan Pop

In said:
Can you give me an example of what you're talking about? I glanced
through <stdio.h> and <string.h> and didn't see anything that looked
like what we're discussing.

Reread your *actual* question and you'll see plenty of things looking like
it. I.e. functions that work on arrays of unspecified size.
I figured as much, which leads me to my real question: If it's
wholly useless, why make it legal syntax?

To simplify the language description. You'd have to introduce a special
case to outlaw them.
To someone who hasn't read
FAQ 6.13 (I'm sure such people exist), it might seem tempting to
declare (*a)[] and then attempt to use it.

No problem, the compiler will promptly complain and the naive programmer
will realise his mistake.

Pointers to arrays are not particularly useful in general, pointers to
the first element of arrays are much more useful in C. The only good
usage I've found for pointers to arrays is the dynamical allocation of
a "two-dimensional" array whose number of columns is known at compile
time. It only takes one malloc call and no additional code, but this
situation is seldom found in practice...

Dan
 
I

Irrwahn Grausewitz

Kghost said:
"Christopher Benson-Manica" <[email protected]> дÈëÓʼþ
[please fix your news reader -^^^^^^^^]
From FAQ 6.13:

int arr[4][5];
int (*a)[]=arr; /* legal, but useless */
~~~~~~~~~~~~~~here error cannot convert to int(*)[] from int[][]

Not so. 'arr' is used in value context and thus decays into a
pointer-to-array, which matches the declaration of 'a'.
maybe int *a[] work better
Huh? Warning: array size missing.
for( i=0;i<4;i++)
a= &arr[0]


This doesn't answer the OP's question.

Regards.
 
D

Dan Pop

In said:
Dan Pop said:
OTOH, if you're talking about pointers to arrays of unspecified size, [yes]
they're useless because pointer arithmetic doesn't work on them.

It also leads me to ask whether the following C program is
conforming...

Pretty much anything can be a conforming C program, you're probably
interested in its strict conformance.
#include <stdio.h>
#include <stdlib.h>

void myfunc( int (*arr)[] )
{
int (*k)[5]=arr;
int i;

for( i=0 ; i<20 ; i++ )
printf( "%d\n", k[i/5][i%5] );
}

int main( void )
{
int arr[4][5];
int (*k)[]=arr;
int i;

printf( "%p == %p\n", (void *)arr, (void *)k );
for( i=0 ; i<20 ; i++ )
arr[i/5][i%5]=i;

myfunc( k );

return EXIT_SUCCESS;
}

Why bother, when a void pointer would do the job as well?
And why bother with a void pointer, when you need to convert it back
to a pointer to an array of the right size?

#define COLS 5

void myfunc(int arr[][COLS], int rows)
{
int i;

for(i = 0; i < rows * COLS; i++)
printf("%d\n", arr[i / COLS][i % COLS]);
}

int main(void)
{
int arr[4][COLS];
...
myfunc(arr, sizeof arr / sizeof arr[0]);
...
}

It's the cleanest usage of a pointer to array, it doesn't even require
the messy declaration of a pointer to an array.

Dan
 
C

Christopher Benson-Manica

Dan Pop said:
Reread your *actual* question and you'll see plenty of things looking like
it. I.e. functions that work on arrays of unspecified size.

You are correct. My *intended* question, as you've no doubt gathered
by now, concerned pointers to arrays of unspecified size. Sorry.
To simplify the language description. You'd have to introduce a special
case to outlaw them.

Would you mind going into details on this? I'm curious...
Pointers to arrays are not particularly useful in general, pointers to
the first element of arrays are much more useful in C. The only good
usage I've found for pointers to arrays is the dynamical allocation of
a "two-dimensional" array whose number of columns is known at compile
time. It only takes one malloc call and no additional code, but this
situation is seldom found in practice...

So something a la

int **a;
a=malloc( 4* sizeof((int*)[5]) ); /* 4x5 array, right? */

?
 
C

Christopher Benson-Manica

Christopher Benson-Manica said:
int **a;
a=malloc( 4* sizeof((int*)[5]) ); /* 4x5 array, right? */
(int(*[5]))

Holy cow. Note to self: copy-paste is my friend. Sorry.
 
D

Dan Pop

In said:
You are correct. My *intended* question, as you've no doubt gathered
by now, concerned pointers to arrays of unspecified size. Sorry.


Would you mind going into details on this? I'm curious...

They're currently allowed not because there is some explicit rule allowing
them but because there is no explicit rule outlawing them. So, to outlaw
them, you need the explicit rule, which would complicate the language
description. What is so difficult to understand?
Pointers to arrays are not particularly useful in general, pointers to
the first element of arrays are much more useful in C. The only good
usage I've found for pointers to arrays is the dynamical allocation of
a "two-dimensional" array whose number of columns is known at compile
time. It only takes one malloc call and no additional code, but this
situation is seldom found in practice...

So something a la

int **a;
a=malloc( 4* sizeof((int*)[5]) ); /* 4x5 array, right? */

?

You got the type of a wrong: it is NOT a pointer to an array. Once you
get it right, you're not likely to get the expression computing the number
of allocated bytes wrong, because it becomes 4 * sizeof *a.

Dan
 
D

Dan Pop

In said:
Christopher Benson-Manica said:
int **a;
a=malloc( 4* sizeof((int*)[5]) ); /* 4x5 array, right? */
(int(*[5]))

Holy cow. Note to self: copy-paste is my friend. Sorry.

I'd write it (int (*)[5]) to be sure it's correct without putting a strain
on my brain, but it shouldn't matter, because a raw type specification
is seldom supposed to be used in a malloc call.

The mere fact that you could not write:

a = malloc(4 * sizeof *a);

should have warned you that a is not correctly defined.

Dan
 
C

Christopher Benson-Manica

Dan Pop said:
Pretty much anything can be a conforming C program, you're probably
interested in its strict conformance.

As always...
Why bother, when a void pointer would do the job as well?
And why bother with a void pointer, when you need to convert it back
to a pointer to an array of the right size?

It wasn't intended to be A Good Thing, just a (pointless) exercise to
see what was strictly legal.
It's the cleanest usage of a pointer to array, it doesn't even require
the messy declaration of a pointer to an array.

Thanks.
 
C

Christopher Benson-Manica

Dan Pop said:
They're currently allowed not because there is some explicit rule allowing
them but because there is no explicit rule outlawing them. So, to outlaw
them, you need the explicit rule, which would complicate the language
description. What is so difficult to understand?

Sorry, I was thinking you were speaking of a rule in the grammar or
something.
int **a;
a=malloc( 4* sizeof((int*)[5]) ); /* 4x5 array, right? */
You got the type of a wrong: it is NOT a pointer to an array. Once you
get it right, you're not likely to get the expression computing the number
of allocated bytes wrong, because it becomes 4 * sizeof *a.

I didn't say a was correctly declared, I just wanted to know if what I
wrote was legal.
 
D

Dan Pop

In said:
Dan Pop said:
int **a;
a=malloc( 4* sizeof((int*)[5]) ); /* 4x5 array, right? */
You got the type of a wrong: it is NOT a pointer to an array. Once you
get it right, you're not likely to get the expression computing the number
of allocated bytes wrong, because it becomes 4 * sizeof *a.

I didn't say a was correctly declared, I just wanted to know if what I
wrote was legal.

Of course it's legal, you can assign the result of any malloc call to any
pointer type. But the comment after the malloc call does not apply to
your code. Your pointer is fairly useless, after being initialised as
above.

You *cannot* use "a" as a bidimensional array after the malloc call.
You have to declare it as a pointer to an array of int if you want
to do that.

Dan
 

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

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top