Reputation: 1307
I found a difference when compiling in c versus when I compile in c++ that I don't fully understand... Let's say I declare an array of char of size 5:
char my_array[5];
From my understanding, "my_array" is effectively a char pointer, which allows me to do this:
char* a = my_array;
Now, I understand that when I declared my array, I allocated 5 bytes only (one for each values in it), which means that "&my_array" should not exist, because there is no allocated memory for a pointer to my_array. To prove that, I did this:
char* b = &my_array; // compiler error in c++, not in c
char** c = &my_array; // compiler error in c++, not in c
I don't get the difference, why would c allow that? Still, let's say I want to convert my char[5] to char*, without using the method for a, I found that I can also do:
char* c = (char*)&my_array; // works both in c and c++
That one I really don't understand. Have I not determined that "&my_array" doesn't exist? More alarmingly, these 2 lines returns the same exact value:
// a and c have the same value (both in c and c++)
char* a = my_array;
char* c = (char*)&my_array;
Next, let's say I want to execute those 5 bytes at run-time, so I declare a new type:
// pFunc is a pointer to function returning void
typedef void (*pFunc)();
Then I tried declaring a pointer to function that would execute my array of bytes:
pFunc pFunc1 = (pFunc)&my_array; // works, but I don't really understand why
pFunc pFunc2 = (pFunc)my_array; // compiler error in c++, not in c
Suddenly, not only is &my_array compiling without problem, but it's also the only way to make this works in c++ (that I know of). Anyone mind explaining to me what is going on? Here is the full code:
#include <stdio.h>
typedef void (*pFunc)();
int main()
{
char my_array[5];
char* a = my_array;
char* b = &my_array; // compiler error in c++, not in c
char* c = (char*)&my_array;
char** d = &my_array; // compiler error in c++, not in c
char** e = (char**)&my_array;
pFunc pFunc1 = (pFunc)&my_array; // works, but I don't really understand why
pFunc pFunc2 = (pFunc)my_array; // compiler error in c++, not in c
printf("char*:\n");
printf("0x%X\n", a);
printf("0x%X\n", b);
printf("0x%X\n", c);
printf("0x%X\n", d);
printf("0x%X\n", e);
printf("\n");
while(1);
return 1;
}
Upvotes: 2
Views: 1064
Reputation: 30569
An array in C++ is not a pointer. When a pointer of the appropriate type is initialized using the array's name (such as when the array is passed to a function argument of the appropriate pointer type), it will decay into a pointer, but it is not itself a pointer.
When you declare char my_array[5]
, you are creating an array of 5 char
s; no pointer is created, but a char[5]
exists and can be pointed to by other pointers.
If you do char* a = my_array;
, my_array
will decay into a pointer; a new char*
is created pointing to the first element of my_array
.
char* b = &my_array;
fails because my_array
isn't a char
, and thus &my_array
isn't a char*
. char** d = &my_array;
fails since my_array
isn't a char*
, and thus &my_array
isn't a char**
. &my_array
is a char (*)[5]
(pointer to an array of 5 char
s). These "work" in C because C only requires the compiler issue a warning for implicit conversion between unrelated pointer types, but C++ does not allow these implicit conversions at all; they result in a compilation error. You need an explicit cast in C++, but even then the behavior is undefined if you dereference the resulting pointer.
Finally, pFunc pFunc1 = (pFunc)&my_array;
"works" on platforms that represent function pointers and object pointers similarly (most modern systems), but it isn't required to work on all platforms. Again, using the resulting pointer will invoke undefined behavior.
pFunc pFunc2 = (pFunc)my_array;
actually compiles as well using GCC, but fails to compile under MSVC. I'm not actually sure which compiler's behavior is correct, but either way the result is unlikely to be anything useful.
Upvotes: 5
Reputation: 106022
When an array is defined then space is allocated for its element in memory. The whole space, in your case 5
bytes, is allocated for array. Therefore, space is allocated for arrays elements as well as array itself.
It should be noted that an array is not a pointer and vice-versa. my_array
is an array and not a pointer. In most cases an array convert to a pointer to its first element, but it does not imply that arrays are pointers.
The address of array my_array
is of type char (*)[5]
, a pointer to an array of 5 char
s. It is incompatible with type char **
and pFunct
. Assigning incompatible pointer types causes error.
Upvotes: 1