简体   繁体   中英

Comparison and assignment between pointer and integer C

I've a theoretical question about these two statements:

Assuming p a pointer to an Integer and a an Integer:

a) if(p==a){.....} or if(p>a) ..

b) p=a ;

All of them are illegal and b is especially dangerous but how does standard C consider them?

Reading the standard, I haven't found if they are errors, undefined behaviors, unspecified behavior, constraint violation, if one of them is legal or other.

Looking in the countless similar question, I haven't found a solution.

All are illegal. To perform comparison, both sides most be convertible to a common type, for assignment, the right-hand side must be convertible to the type of the left-hand side, and:

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.4 , 3; 6.5.16.1 describes some exceptions for the null pointer constant, void pointers and _Bool in the case of assignment.)

When you do add explicit casts to convert the pointers to integers, the program becomes valid again and you will get booleans from the comparisons. The results are implementation-dependent. Be sure to use uintptr_t when storing pointers in integers.

C11 (n1570) §6.5.8 [Relational operators] / 2:

Constraints

One of the following shall hold:

  • both operands have real type ; or
  • both operands are pointers to qualified or unqualified versions of compatible object types.

(real type means the integer types, enums, real floating point types and char (§6.2.5/17))

§6.5.9 [Equality operators]

Constraints

One of the following shall hold:

  • both operands have arithmetic type ;
  • both operands are pointers to qualified or unqualified versions of compatible types;
  • one operand is a pointer to an object type and the other is a pointer to a qualified or unqualified version of void ; or
  • one operand is a pointer and the other is a null pointer constant.

§6.5.16.1 [Simple assignment] / 1:

Constraints

One of the following shall hold:

  • the left operand has atomic, qualified, or unqualified arithmetic type , and the righ 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 .

Basically, all 3 expressions violated the constraints set in the expression.


What does violating constraints mean? Errors? But nowhere says that violation of constraints shall cause the translation to fail. The C standard doesn't seem to be very clear, but the closest interpretation would be:

§4 [Conformance] / 2:

If a “shall” or “shall not” requirement that appears outside of a constraint or runtime-constraint is violated, the behavior is undefined.

but this talks about outside of constraints; and §5.1.1.3 [Diagnostics] / 1:

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. Diagnostic messages need not be produced in other circumstances.

so the compiler needs to at least produce a message (as we can see in gcc), but did not say what they should do after that.

The example after this paragraph mentions that

EXAMPLE

An implementation shall issue a diagnostic for the translation unit:

  char i; int i; 

because in those cases where wording in this International Standard describes the behavior for a construct as being both a constraint error and resulting in undefined behavior , the constraint error shall be diagnosed.

and §6.7 [Declarations] / 3 does not explicitly mention that violating the Constraint will cause undefined behavior.

Therefore, I deduce that your 3 expressions are all undefined behaviors, accompanied with diagnostic messages .

Both a) and b) are constraint violations. C99 , § 6.5.8 , § 6.5.9, and § 6.5.16.1.

I don't know if I'm actually answering your question, but here goes. Concerning a), you have a comparison, so what you're basically saying is "does the pointer have the memory address a?". In b) you're assigning to the pointer the value a, which means you are saying it will point to the memory address "a". Here go a few tips:

p=&a

Your pointer is now pointing to the memory address of integer a.

*p=a

The value to which your pointer is pointing takes the value of a.

p=a

Your pointer is now pointing to the memory value a.

Hope it helped!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM