繁体   English   中英

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

[英]Comparison and assignment between pointer and integer C

我对这两个陈述有一个理论上的问题:

假设p的指针整数和a整数:

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

b) p=a ;

所有这些都是非法的, b特别危险,但标准C如何考虑它们?

阅读标准,我没有发现它们是错误,未定义的行为,未指定的行为,违反约束,如果其中一个是合法的或其他的。

看着无数类似的问题,我还没有找到解决方案。

一切都是非法的。 为了进行比较,双方大多数可以转换为普通类型,对于赋值,右侧必须可以转换为左侧的类型,并且:

除了6.5.16.1的约束允许之外,涉及指针的转换应通过显式转换来指定。

(6.5.4,3; 6.5.16.1描述了空指针常量,一些例外void指针和_Bool在分配的情况下)。

当您添加显式转换以将指针转换为整数时,程序再次变为有效,您将从比较中获得布尔值。 结果取决于实现。 在以整数存储指针时,请务必使用uintptr_t

C11(n1570)§6.5.8[关系运算符] / 2:

约束

以下其中一项应持有:

  • 两个操作数都有实物类型 ; 要么
  • 两个操作数都是指向兼容对象类型的限定或非限定版本的指针

(实数类型表示整数类型,枚举,实数浮点类型和char (§6.2.5/ 17))

§6.5.9[平等运营商]

约束

以下其中一项应持有:

  • 两个操作数都有算术类型 ;
  • 两个操作数都是指向兼容类型的限定或非限定版本的指针 ;
  • 一个操作数是指向对象类型的指针 ,另一个是指向合格或非限定版本的void指针 ; 要么
  • 一个操作数是一个指针 ,另一个是指针常量。

§6.5.16.1[简单分配] / 1:

约束

以下其中一项应持有:

  • 左操作数具有原子,限定或非限定算术类型 ,并且righ具有算术类型 ;
  • 左操作数具有与右侧类型兼容的结构或联合类型的原子,限定或非限定版本;
  • 左操作数具有原子,限定或非限定指针类型 ,并且(考虑左值操作数在左值转换后将具有的类型)两个操作数都是指向兼容类型的限定或非限定版本的指针 ,左侧指向的类型具有全部右边指出的那种限定词;
  • 左操作数具有原子,限定或非限定指针类型 ,并且(考虑左值操作数在左值转换后将具有的类型)一个操作数是指向对象类型的指针 ,另一个是指向合格或非限定版本的指针 void ,左边指向的类型具有右边指向的所有类型的限定符;
  • 左操作数是一个原子,限定或非限定指针 ,右边是一个指针常量; 或左操作数具有类型为atomic,qualified或_Bool ,右边是指针

基本上,所有3个表达式都违反了表达式中设置的约束


违反约束意味着什么? 错误? 但是没有地方说违反约束会导致翻译失败。 C标准似乎不是很清楚,但最接近的解释是:

§4[符合性] / 2:

如果违反了出现在约束或运行时约束之外的“应该”或“不应该”的要求,则行为是不确定的。

但这谈到了限制之外 ; 和§5.1.1.3[诊断] / 1:

如果预处理转换单元或转换单元包含违反任何语法规则或约束的情况 ,则符合要求的实现应生成至少一条诊断消息(以实现定义的方式标识),即使该行为也明确指定为未定义或实现 -定义。 在其他情况下不需要产生诊断消息。

因此编译器至少需要生成一条消息(正如我们在gcc中看到的那样),但没有说明之后他们应该做什么。

本段后面的例子提到了这一点

实施应为翻译单位发布诊断:

  char i; int i; 

因为在本国际标准中的措辞将构造的行为描述为约束错误并导致未定义的行为的情况下 ,应诊断约束错误。

和§6.7[声明] / 3没有明确提到违反约束将导致未定义的行为。

因此,我推断出您的3个表达式都是未定义的行为,并伴有诊断消息

a)和b)都是约束违规。 C99 ,§6.5.8,§6.5.9和§6.5.16.1。

我不知道我是否真的在回答你的问题,但现在就去了。 关于a),你有一个比较,所以你基本上说的是“指针是否有内存地址a?”。 在b)你将指针指定给值a,这意味着你说它将指向内存地址“a”。 这里有一些提示:

p=&a

你的指针现在指向整数a的内存地址。

*p=a

指针指向的值采用a的值。

p=a

你的指针现在指向内存值a。

希望它有所帮助!

暂无
暂无

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

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