问题
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), is wrong.
int *ptoi = 17; // I assumed that 17 is being automatically casted to int *
I know that if I do the same thing as above in C++, I get an error saying invalid conversion from int to int *
. But if I do the following in C++, it works fine:
int *ptoi = (int *)17;
These are the reasons I thought that in C, the casting was implicit.
Can someone please explain why, in C++, I have to cast it but in C, it works fine?
回答1:
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.
回答2:
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.
回答3:
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
回答4:
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.
来源:https://stackoverflow.com/questions/8288502/why-can-i-implicitly-convert-an-int-literal-to-an-int-in-c-but-not-in-c