The following observation arose as I was following this question about char[] and char* differences.
#include <iostream>
typedef char ar[];
typedef char* pr;
void f2(ar x, pr y)
{
std::cout << std::is_same<decltype(x), decltype(y)>::value << '\n';
std::cout << std::is_same<ar, pr>::value << '\n';
}
int main()
{
char data[] = "data";
char *ptr = data;
f2(data,ptr);
return 0;
}
Output ( on Apple LLVM version 4.2 (clang-425.0.28) )
1
0
Why do these report as different types, but not different decltype()s ? My suspicion is they are in fact different types due to their typedef declarations, but then why are variables reported as the same type?
In C++, as in C, a parameter that's declared to be of array type is adjusted (at compile time) to be of pointer type, specifically a pointer to the array's element type.
This happens whether the array type is specified directly or via a typedef (remember that a typedef doesn't create a new type, just an alias for an existing type).
So this:
typedef char ar[];
typedef char* pr;
void f2(ar x, pr y)
{
// ...
}
really means:
void f2(char* x, char* y)
{
// ...
}
Another rule, also shared by C and C++, is that an expression of array type is, in most but not all contexts, implicitly converted to a pointer to the first element of the array object. Which means that if you define an array object:
char arr[10];
you can use the name of that object as an argument to a function that takes a char* parameter (which loses the bounds information).
In C, the cases where this implicit conversion doesn't happen are:
sizeof (sizeof arr yields the size of the array, not the size of a pointer);& (&arr is a pointer-to-array, not a pointer-to-pointer); andchar s[] = "hello"; initializes s as an array, not as a pointer).None of these cases (or the other cases that occur in C++) appear in your program, so your call:
f2(data,ptr);
passes two pointer values of type char* to f2.
Inside f2, the parameter objects x and y are both of type char*, so std::is_same<decltype(x), decltype(y)>::value is true.
But the types ar and pr are distinct. ar is an incomplete array type char[], and pr is the pointer type char*.
Which explains your program's output. The weirdness happens because the parameter x, which you defined with the array type ar, is really of type char*, which is the same type as pr.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With