char (*ptr)[]

R

Rafal Dabrowa

What does mean such declaration:

void f( char (*ptr)[] );

Is this the same as

void f( char **ptr );

or not ?


Rafal
 
W

Walter Roberson

: void f( char (*ptr)[] );
:Is this the same as
: void f( char **ptr );
:eek:r not ?

In the first, there is a hint to the reader that what is pointed to is a
constant pointer -- instead of it being the case that you are pointing to
a pointer that you might be updating.

I do not recall whether there is any difference semantically; I'm sure
someone will chime in ;-)
 
I

infobahn

Rafal said:
What does mean such declaration:

void f( char (*ptr)[] );

Is this the same as

void f( char **ptr );

or not ?


They are not the same.

void f(char (*ptr)[]);

declares a function f that takes an argument which is a pointer
to an array of char, and that returns no value.

void f(char **ptr);

declares a function f that takes an argument which is a pointer
to a pointer to char, and that returns no value.

Pointers are not arrays.
 
L

Luke Wu

Rafal said:
What does mean such declaration:

void f( char (*ptr)[] );

Does your compiler accept this declaration? I would think the
dimension is required.
Is this the same as

void f( char **ptr );

or not ?


Rafal



They are very different. The first ptr, points to a whole array, so if
u do pointer arithmetic (like ptr++), you step over the total size of
the array, which is missing in your case. The second ptr, points to a
pointer, which in turn points to an array. So doing something like
ptr++ would increment by the sizeof(char *).
 
A

Andrey Tarasevich

Luke said:
Rafal said:
What does mean such declaration:

void f( char (*ptr)[] );

Does your compiler accept this declaration? I would think the
dimension is required.
...

It is required in C++. In C the above declaration is legal.
 
O

Old Wolf

Walter said:
Rafal Dabrowa said:
What does mean such declaration:
void f( char (*ptr)[] );
Is this the same as
void f( char **ptr );
or not ?

In the first, there is a hint to the reader that what is pointed
to is a constant pointer

Where? I don't see 'const' anywhere.
-- instead of it being the case that you are pointing to a pointer
that you might be updating.

You can update ptr and *ptr, if you want.
I do not recall whether there is any difference semantically; I'm sure
someone will chime in ;-)

In the second, ptr points to a pointer to char.
In the first, ptr points to an array of char (of unknown size
-- *ptr has incomplete type). You can still use (*ptr) because of
"The Rule", ie. it becomes a pointer to char in most expressions.
 
W

Walter Roberson

:> > void f( char (*ptr)[] );

:> In the first, there is a hint to the reader that what is pointed
:> to is a constant pointer

:Where? I don't see 'const' anywhere.

I said a hint to the reader, not a hint to the compiler.

array[subscript] where array is a variable (rather than an expression)
implies that the array location is a constant far as that block of code
is concerneid, so when someone takes the trouble to write the extra
() and [] then they are usually trying to emphasize that what ptr points
to is a value that is not going to change.
 
K

Kiru Sengal

Walter said:
:> > void f( char (*ptr)[] );

:> In the first, there is a hint to the reader that what is pointed
:> to is a constant pointer

:Where? I don't see 'const' anywhere.

I said a hint to the reader, not a hint to the compiler.

array[subscript] where array is a variable (rather than an expression)
implies that the array location is a constant far as that block of code
is concerneid, so when someone takes the trouble to write the extra
() and [] then they are usually trying to emphasize that what ptr points
to is a value that is not going to change.

I had to read your post a couple times to figure out what you 'mean.'
You're thinking of accessing 2 dimensional arrays with two levels of
indirection --which is correct-- but you are assuming a mechanism where
there is an array of "constant intermediate stage pointers" that point
to the subarrays. You are better off not thinking this way, because
there really isn't an array of pointers that holds together 2
dimensional arrays in the execution evironment. The mechanism by which
double indirection works with 2-dimensional arrays is different, and
your nearest C textbook should explain this.

No matter how many dimensions an array has, the elements are contiguous
in the abstract machine C describes. If an array has more than 1
dimension, these other dimensions (other than the first dimension,
which is dealt via the pointer method you're probably aware of)
describe how to "step over" parts of the contiguous elements to find
the proper element.
 
O

Old Wolf

Walter said:
Old Wolf said:
Walter said:
void f( char (*ptr)[] );
In the first, there is a hint to the reader that what is pointed
to is a constant pointer
Where? I don't see 'const' anywhere.

I said a hint to the reader, not a hint to the compiler.

array[subscript] where array is a variable (rather than an
expression) implies that the array location is a constant
far as that block of code is concerneid, so when someone
takes the trouble to write the extra () and []

You speak as if the () and [] don't make any difference.

char (*ptr)[] is a completely different type to char *ptr[],
and it isn't possible to write it without the [] .
then they are usually trying to emphasize that what ptr points
to is a value that is not going to change.

Never heard that one before. Anyway, as you might have gathered
by now, char (*ptr)[] is quite a different kettle of fish to
your average foo[bar] .
 
V

Villy Kruse

Never heard that one before. Anyway, as you might have gathered
by now, char (*ptr)[] is quite a different kettle of fish to
your average foo[bar] .


Is it possible to express (*ptr)[] using an intermediate typedef?

typedef thingy ????;
thingy *ptr;

and what type is thingy going to be?


Villy
 
E

Emmanuel Delahaye

Luke Wu wrote on 23/02/05 :
Rafal said:
What does mean such declaration:

void f( char (*ptr)[] );

Does your compiler accept this declaration? I would think the
dimension is required.

I thought too, but it is accepted in C in a parameter context, but I
consider it bad practice, because there is no indication of the size.
It, somehow, 'anonymizes' the array (in terms of size).

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

void f(char (*ptr)[])
{
(*ptr)[0] = 'a';
(*ptr)[1] = 'b';
(*ptr)[2] = 'c';
(*ptr)[3] = 0;
}

int main (void)
{
char a[123];

f(&a);

printf ("'%s'\n", a);

system ("pause");
return 0;
}

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"C is a sharp tool"
 
K

Kenneth Bull

Emmanuel said:
Luke Wu wrote on 23/02/05 :
Rafal said:
What does mean such declaration:

void f( char (*ptr)[] );

Does your compiler accept this declaration? I would think the
dimension is required.

I thought too, but it is accepted in C in a parameter context, but I
consider it bad practice, because there is no indication of the size.
It, somehow, 'anonymizes' the array (in terms of size).

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

void f(char (*ptr)[])
{
(*ptr)[0] = 'a';
(*ptr)[1] = 'b';
(*ptr)[2] = 'c';
(*ptr)[3] = 0;
}

int main (void)
{
char a[123];

f(&a);

printf ("'%s'\n", a);

system ("pause");
return 0;
}

Correct, but totally useless method.
 
E

E. Robert Tisdale

Andrey said:
Luke said:
Rafal said:
What does mean such declaration:

void f( char (*ptr)[] );

Does your compiler accept this declaration? I would think the
dimension is required.
...

It is required in C++. In C the above declaration is legal.

C++ deprecated this feature of C, so we should try to avoid it in our C
programs.
 
W

Walter Roberson

:C++ deprecated this feature of C, so we should try to avoid it in our C
:programs.

Hmmm? C++ is a different language, one that deprecates a number of
features of it's C heritage. I don't think it follows that we should
avoid all those features in C, considering that C has no replacement
for some of them.
 
I

infobahn

E. Robert Tisdale said:
Andrey said:
Luke said:
Rafal Dabrowa wrote:
What does mean such declaration:

void f( char (*ptr)[] );


Does your compiler accept this declaration? I would think the
dimension is required.
...

It is required in C++. In C the above declaration is legal.

C++ deprecated this feature of C, so we should try to avoid it in our C
programs.

That doesn't follow. C++ is not C, and C is not C++. The construct
is legal C, and makes perfect sense. The only reason we might wish
to avoid it from a syntactical point of view is if we have some
rather strange reason for wanting to write our code in the rather
limited common subset of C and C++. Few of us have such a need; we
are not all pjp.
 
M

Mark McIntyre

array[subscript] where array is a variable (rather than an expression)
implies that the array location is a constant far as that block of code

er, no it doesn't. AFAICS there's nothing in the C standard that requires
the implementation to leave the location of an array invariant, so long as
x[y] still finds the yth element of x.

Or are you trying to say something quite different and misexpressing it?
Perhaps something todo with array names not being lvalues?
 
W

Wayne Rasmussen

Emmanuel said:
Luke Wu wrote on 23/02/05 :
Rafal said:
What does mean such declaration:

void f( char (*ptr)[] );

Does your compiler accept this declaration? I would think the
dimension is required.


I thought too, but it is accepted in C in a parameter context, but I
consider it bad practice, because there is no indication of the size.
It, somehow, 'anonymizes' the array (in terms of size).
In c, we do not have to give a size for an array or the first row in a
multiarray.
 
A

Andrey Tarasevich

Wayne said:
...
What does mean such declaration:

void f( char (*ptr)[] );


Does your compiler accept this declaration? I would think the
dimension is required.


I thought too, but it is accepted in C in a parameter context, but I
consider it bad practice, because there is no indication of the size.
It, somehow, 'anonymizes' the array (in terms of size).
In c, we do not have to give a size for an array or the first row in a
multiarray.

In C the declaration

void foo(T p[])

is equivalent to

void foo(T* p)

and vice versa.

For this reason, the declaration is question is technically equivalent to

void f(char ptr[][]);

i.e. it omits the _second_ dimension in a multiarray. Fortunately, C
declaration rules prohibit array declarations of 'T[][]' form, which
makes the latter declaration ill-formed.
 
A

Andrey Tarasevich

Villy said:
Never heard that one before. Anyway, as you might have gathered
by now, char (*ptr)[] is quite a different kettle of fish to
your average foo[bar] .
Is it possible to express (*ptr)[] using an intermediate typedef?

typedef thingy ????;
thingy *ptr;

Yes.

typedef char thingy[];

void f(thingy *ptr);
and what type is thingy going to be?

Array of 'char' of unknown size.
 
L

Lawrence Kirby

Luke Wu wrote on 23/02/05 :
Rafal said:
What does mean such declaration:

void f( char (*ptr)[] );

Does your compiler accept this declaration? I would think the
dimension is required.

I thought too, but it is accepted in C in a parameter context, but I
consider it bad practice, because there is no indication of the size.
It, somehow, 'anonymizes' the array (in terms of size).

That may be a reasonable thing to do, especially when you don't know the
size of the array or it isn't a compile time constant (noting that you can
use VLAs for some contexts of this in C99). However function parameters
are not the only place where incomplete array types can occur. Consider:


file1.h

extern char name[];


file1.c

#include "file1.h"
char name[] = "George";


file2.c

#include "file1.h"


Here name is an array with static storage duration defined in file1.c.
file2.c can access it through the declaration in file1.h but the size of
the array is not available. I can change name's initialiser (specifically
its length) in file1.c without breaking anything. However I can still use
it as a string in file2.c. With respect ti the subject of this thread I
could also write the following in file2.c.

char (*ptr)[] = &name;

although there isn't an obvious reason for doing so. Pointers can point to
almost anything, including incomplete types.

Lawrence
 

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,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top