问题
I wrote a simple C program and I was expecting that it will fail in compilation but unfortunately it compiles and runs fine in C, but fails in compilation in C++. Consider below program:
#include <stdio.h>
int main()
{
char *c=333;
int *i=333;
long *l=333;
float *f=333;
double *d=333;
printf("c = %u, c+1 = %u",c,c+1);
return 0;
}
Visit this link: http://ideone.com/vnKZnx
I think that this program definitely can't compile in C++ due to C++'s strong type checking. Why this program compiles in C? It is the fact that compiler shows warnings also. I am using Orwell Dev C++ IDE(gcc 4.8.1 compiler). I also tried same program on other compiler (Borland Turbo C++ 4.5) , saved it by extension .c and on this compiler it failed to compile.
回答1:
This code is neither legal C nor legal C++.
N1570 §6.7.9/p11:
The initializer for a scalar shall be a single expression, optionally enclosed in braces. The initial value of the object is that of the expression (after conversion); the same type constraints and conversions as for simple assignment apply, taking the type of the scalar to be the unqualified version of its declared type.
§6.5.16.1/p1 provides that for simple assignment:
One of the following shall hold:
- the left operand has atomic, qualified, or unqualified arithmetic type, and the right has arithmetic type;
- the left operand has an atomic, qualified, or unqualified version of a structure or union type compatible with the type of the right;
- the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) both operands are pointers to qualified or unqualified versions of compatible types, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;
- the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) one operand is a pointer to an object type, and the other is a pointer to a qualified or unqualified version of
void
, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;- the left operand is an atomic, qualified, or unqualified pointer, and the right is a null pointer constant; or
- the left operand has type atomic, qualified, or unqualified
_Bool
, and the right is a pointer.
None of which matches a pointer on the left and 333
on the right. §6.5.16.1/p1 is a constraint, and conforming implementations are required to produce a diagnostic upon a constraint violation (§5.1.1.3/p1):
A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint, even if the behavior is also explicitly specified as undefined or implementation-defined.
It happens that GCC decides to produce a warning instead of an error in C mode and continue to compile it, but it doesn't have to.
回答2:
C can convert numbers to pointers. char* c = 123
will set c
to point to the 123rd byte in memory.
While this is nearly useless and almost certainly an error in desktop programming, in embedded systems it is necessary to interface with the hardware, which may look for values in certain, hardcoded memory addresses.
回答3:
Ethnically there is nothing wrong with your code. You are initializing the pointers with the integer constant values 333. and then printing the address. The warning it shows is probably because the integer value is type casted to address type.
the problem will start when you would try to dereference the pointers. It will give segmentation fault.
来源:https://stackoverflow.com/questions/25725255/why-this-program-that-performs-invalid-pointer-initialization-compiles-fine-in-c