Pointer-to-array issues in C vs C++

R

Robbie Hatley

It points to it. (The name of an array is also a pointer to it.)

No, the name of an array decays to a pointer to the first element of the
array. A pointer to an array and a pointer to the first element of an array
are not the same thing.

int a[10];
cout << &a + 1 << endl;
cout << a + 1 << endl;

The two statements print different pointer values, proving that a pointer to
an array (first case) and a pointer to the first element of an array (second
case) are not the same.

I was dubious, so I wrote this program:

#include <iostream>
using std::cout;
using std::endl;
int main(void)
{
int a[10];
cout << "int a[10];" << endl;
cout << " &a : " << (&a) << endl;
cout << " a : " << ( a) << endl;
cout << "&a + 1 : " << (&a + 1) << endl;
cout << " a + 1 : " << ( a + 1) << endl;
return 0;
}

and I got these results:

wd=C:\C\test
%array-pointer-test
int a[10];
&a : 0x6cffac
a : 0x6cffac
&a + 1 : 0x6cffd4
a + 1 : 0x6cffb0

Interestingly, the value of &a and a are the same. But when incremented,
one increments 4 bytes, the other 40 bytes.

Of course. They're pointers to different types, one of size 4 and the other
of size 40. I should have known that. ::: kicks self :::

In C, however, depending on the context, the compiler is likely to
implicitly cast the pointer from pointer-to-array to pointer-to-int.
For example, consider the following code:

/* char-array-test.c */
#include <stdio.h>
char Func(char* blat)
{
return *(blat+1);
}
int main(void)
{
char a[80];
a[0] = 'n';
a[1] = 't';
printf("Func(&a) = %c\n", Func(&a));
return 88;
}

This prints 't' in C, but it won't even compile in C++.

I think I shouldn't have learned C before C++; I've picked up some bad
habits that way.

--
Cheers,
Robbie Hatley
Tustin, CA, USA
email: lonewolfintj at pacbell dot net
web: home dot pacbell dot net slant earnur slant
 
V

Victor Bazarov

Robbie Hatley said:
[...]
I was dubious, so I wrote this program:

#include <iostream>
using std::cout;
using std::endl;
int main(void)
{
int a[10];
cout << "int a[10];" << endl;
cout << " &a : " << (&a) << endl;
cout << " a : " << ( a) << endl;
cout << "&a + 1 : " << (&a + 1) << endl;
cout << " a + 1 : " << ( a + 1) << endl;
return 0;
}

and I got these results:

wd=C:\C\test
%array-pointer-test
int a[10];
&a : 0x6cffac
a : 0x6cffac
&a + 1 : 0x6cffd4
a + 1 : 0x6cffb0

Interestingly, the value of &a and a are the same. But when incremented,
one increments 4 bytes, the other 40 bytes.

Of course. They're pointers to different types, one of size 4 and the other
of size 40. I should have known that. ::: kicks self :::

In C, however, depending on the context, the compiler is likely to
implicitly cast the pointer from pointer-to-array to pointer-to-int.

I just wonder how you come to this conclusion.
For example, consider the following code:

/* char-array-test.c */
#include <stdio.h>
char Func(char* blat)
{
return *(blat+1);
}
int main(void)
{
char a[80];
a[0] = 'n';
a[1] = 't';
printf("Func(&a) = %c\n", Func(&a));

So, inside that function the address that you obtain by &a, is still
interpreted as char*, as if you passed 'a' (instead of &a). What is
surprising about that?

In C, anything used to be convertible to char* (and back). Similar to
void* in C++ (and now in C99, IIRC). The difference is that you can't
really do anything with void*, whereas char* can be interpreted as
a string (or array of characters). IMO, C++ fixed what was kind of
broken in C. Or at least tried to fix it. C gived char* dual meaning
-- a generic address holder and a pointer to [an array of] character.
return 88;
}

This prints 't' in C, but it won't even compile in C++.

Of course it won't compile in C++. VC++ 7.1 (when compiling C) does
actually warn about the difference in "levels of indirection". It
lets the difference slide simply because C was built to serve that.
I think I shouldn't have learned C before C++; I've picked up some bad
habits that way.

Learing C _correctly_ before C++ can't hurt, at least not too much.
Bad habits can be picked in either language and without them. Try
not to blame languages for the way they are [mis]used.

Also, knowing the differnces between the languages and how they do
things they do and what is allowed and not allowed there always
helps.

Don't beat yourself too much...

Victor
 
J

Jack Klein

Q1 . What is the use of pointer to an array?

It points to it. (The name of an array is also a pointer to it.)

No, the name of an array decays to a pointer to the first element of the
array. A pointer to an array and a pointer to the first element of an array
are not the same thing.

int a[10];
cout << &a + 1 << endl;
cout << a + 1 << endl;

The two statements print different pointer values, proving that a pointer to
an array (first case) and a pointer to the first element of an array (second
case) are not the same.

I was dubious, so I wrote this program:

#include <iostream>
using std::cout;
using std::endl;
int main(void)
{
int a[10];
cout << "int a[10];" << endl;
cout << " &a : " << (&a) << endl;
cout << " a : " << ( a) << endl;
cout << "&a + 1 : " << (&a + 1) << endl;
cout << " a + 1 : " << ( a + 1) << endl;
return 0;
}

and I got these results:

wd=C:\C\test
%array-pointer-test
int a[10];
&a : 0x6cffac
a : 0x6cffac
&a + 1 : 0x6cffd4
a + 1 : 0x6cffb0

Interestingly, the value of &a and a are the same. But when incremented,
one increments 4 bytes, the other 40 bytes.

Of course. They're pointers to different types, one of size 4 and the other
of size 40. I should have known that. ::: kicks self :::

In C, however, depending on the context, the compiler is likely to
implicitly cast the pointer from pointer-to-array to pointer-to-int.
For example, consider the following code:

Actually, depending on the compiler ***and the way you invoke it***.

If you invoke your compiler as a conforming C compiler (which none I
know of are by default), it must issue a diagnostic when you pass a
pointer to an array to a function prototyped as accepting a pointer to
char.

Asking the compiler to perform that conversion explicitly is a
constraint violation.

Check the compiler's documentation and invoke it in standard C
conforming mode, and it will no more accept the program without
complaint than will a C++ compiler.
 

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,967
Messages
2,570,148
Members
46,694
Latest member
LetaCadwal

Latest Threads

Top