简体   繁体   English

指针和整数C之间的比较和赋值

[英]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: 假设p的指针整数和a整数:

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

b) p=a ; b) p=a ;

All of them are illegal and b is especially dangerous but how does standard C consider them? 所有这些都是非法的, b特别危险,但标准C如何考虑它们?

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.16.1的约束允许之外,涉及指针的转换应通过显式转换来指定。

( 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.) (6.5.4,3; 6.5.16.1描述了空指针常量,一些例外void指针和_Bool在分配的情况下)。

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. 在以整数存储指针时,请务必使用uintptr_t

C11 (n1570) §6.5.8 [Relational operators] / 2: C11(n1570)§6.5.8[关系运算符] / 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)) (实数类型表示整数类型,枚举,实数浮点类型和char (§6.2.5/ 17))

§6.5.9 [Equality operators] §6.5.9[平等运营商]

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 ; 一个操作数是指向对象类型的指针 ,另一个是指向合格或非限定版本的void指针 ; or 要么
  • one operand is a pointer and the other is a null pointer constant. 一个操作数是一个指针 ,另一个是指针常量。

§6.5.16.1 [Simple assignment] / 1: §6.5.16.1[简单分配] / 1:

Constraints 约束

One of the following shall hold: 以下其中一项应持有:

  • the left operand has atomic, qualified, or unqualified arithmetic type , and the righ has arithmetic type ; 左操作数具有原子,限定或非限定算术类型 ,并且righ具有算术类型 ;
  • 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; 左操作数具有原子,限定或非限定指针类型 ,并且(考虑左值操作数在左值转换后将具有的类型)一个操作数是指向对象类型的指针 ,另一个是指向合格或非限定版本的指针 void ,左边指向的类型具有右边指向的所有类型的限定符;
  • 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 . 或左操作数具有类型为atomic,qualified或_Bool ,右边是指针

Basically, all 3 expressions violated the constraints set in the expression. 基本上,所有3个表达式都违反了表达式中设置的约束


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: C标准似乎不是很清楚,但最接近的解释是:

§4 [Conformance] / 2: §4[符合性] / 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: 和§5.1.1.3[诊断] / 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. 因此编译器至少需要生成一条消息(正如我们在gcc中看到的那样),但没有说明之后他们应该做什么。

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. 和§6.7[声明] / 3没有明确提到违反约束将导致未定义的行为。

Therefore, I deduce that your 3 expressions are all undefined behaviors, accompanied with diagnostic messages . 因此,我推断出您的3个表达式都是未定义的行为,并伴有诊断消息

Both a) and b) are constraint violations. a)和b)都是约束违规。 C99 , § 6.5.8 , § 6.5.9, and § 6.5.16.1. C99 ,§6.5.8,§6.5.9和§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?". 关于a),你有一个比较,所以你基本上说的是“指针是否有内存地址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". 在b)你将指针指定给值a,这意味着你说它将指向内存地址“a”。 Here go a few tips: 这里有一些提示:

p=&a

Your pointer is now pointing to the memory address of integer a. 你的指针现在指向整数a的内存地址。

*p=a

The value to which your pointer is pointing takes the value of a. 指针指向的值采用a的值。

p=a

Your pointer is now pointing to the memory value a. 你的指针现在指向内存值a。

Hope it helped! 希望它有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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