I believed that in the following code, C \"automatically casts 17 to an int *
\" which, as someone recently pointed out (but did not give the reasons as to why),
It has been, C has implicit conversions - in my experience pretty much from any integral type to any other integral type. Pointers in C are considered integralscalar
types.
In C++, Integral Types are defined as follows:
Types
bool
,char
,char16_t
,char32_t
,wchar_t
, and thesigned
andunsigned
integer types are collectively called integral types.48 A synonym for integral type is integer type. The representations of integral types shall define values by use of a pure binary numeration system.49 [ Example: this International Standard permits 2’s complement, 1’s complement and signed magnitude representations for integral types. —end example ]
The only integral value that can be converted to pointer type in C++ is the null pointer constant, though technically the conversion is to a prvalue
of type std::nullptr_t
. (para 4.10)
Final Note
Instead of fixing it like this:
int *ptoi = (int *)17;
considering adding the C++-style cast:
int *ptoi = reinterpret_cast<int*>(17);
to make it clear what kind of conversion you are trying to invoke
Conversions from integers to pointers without casts are also illegal in C. Most compilers will let you get away with it though. Clang gives a warning:
example.c:5:8: warning: incompatible integer to pointer conversion initializing
'int *' with an expression of type 'int'
int *x = 17;
^ ~~
C99 says in Section 6.5.4 Cast operators, paragraph 4:
Conversions that involve pointers, other than where permitted by the constraints of 6.5.16.1, shall be specified by means of an explicit cast.
6.5.16.1 is the exception for void *
converting to other pointers without needing a cast.
The C++ spec says in Section 5.4 Explicit type conversion (cast notation), paragraph 3:
Any type conversion not mentioned below and not explicitly defined by the user is ill-formed.
So there you go - illegal in both languages, but for compatibility with lots of older software, a lot of C compilers will let you get away with it.
The compiler will interpret int *ptoi = 17;
as a variable ptoi that points to an integer at location 17 (0x00000011).
C is simply a completely different language. It may look like C++, but it's not. Different rules apply to both languages.
I should probably point out that both C and C++ will (as far as I know) make it a pointer to 0x00000011, but C simply complains less, since assigning memory locations is something that's not invalid in C.
Yes, the casting is implicit in C, although many (all?) compilers give a warning. In C++, no implicit conversion is performed from int
to int*
, so the explicit cast is required.