6.5.16 赋值操作符

语法

1、assignment-expression:

conditional-expression

unary-expression    assignment-operator     assignment-expression

assignment-operator: 以下之一

        =    *=    /=    %=    +=    -=    <<=    >>=    &=    ^=    |=

约束

2、一个赋值操作符应该具有一个可修改的左值作为其左操作数。

语义

3、一个赋值操作符将一个值存储在由左操作数所指派的对象中。一个赋值表达式在赋值后具有左操作数的值,[注:允许实现读此对象以确定该值,但不要求这么做,即使对象是用volatile限定的类型。]但并不是一个左值。赋值表达式的类型是左操作数的类型,在左值转换后即可具有。更新左操作数所存放的值的副作用顺序在左和右操作数的值计算之后。操作数的计算是没有顺序的。

6.5.16.1 简单赋值

约束

1、要遵守下列规则之一:[注:对于这些关于类型限定符的非对称的出现是由于将左值变为“表达式的值”并移除了任一类型限定符的转换(在6.3.2.1中指定)被应用于表达式的类型类别(比如,int volatile * const移除了const,但并不移除volatile)。]

——左操作数具有原子的、限定的、或非限定的算术类型,而右操作数具有算术类型;

——左操作数具有与右操作数相兼容的一个原子的、限定的、或非限定版本的一个结构体或联合体类型;

——左操作数具有原子的、限定的、或非限定的指针类型,且(考虑到左操作数在左值转换之后将会有的类型)两个操作数都具有指向限定或非限定版本的兼容类型的指针,而被左操作数所指向的类型具有被右值所指向的类型的所有限定符。

——左操作数具有原子的、限定的、或非限定的类型,且其中一个操作数是一个指向一个对象类型的指针,而另一个是一个指向一个限定或非限定版本的void的指针,而被左操作数所指向的类型具有被右操作数所指向类型的所有限定符。

——左操作数是一个原子的、限定的、或非限定的指针,而右操作数是一个空指针常量;或

——左操作数具有原子的、限定的、或非限定的_Bool,而右操作数是一个指针。

语义

2、在简单赋值(=)中,右操作数的值被转换为赋值表达式的类型,并替换由左操作数所指派的对象中的值。

3、如果正要存在一个对象中的值从另一个对象被读,两者以任一种形式叠交,那么该叠交应该是准确的,且两个对象应该具有一个兼容类型的限定或非限定版本;否则,行为是未定义的。

4、例1 在下列程序片段中

int f(void);
char c;
/* ... */
if( (c = f()) == -1 )
/* ... */

由函数所返回的int值可以被截断,当存储在char中时,然后在比较之前被转换回int宽度。在某一实现中,其“平凡的”char具有与unsigned char具有相同范围(并且charint要窄),那么转换结果不能是负数,这样比较的操作数可能永远不会比较为相等的。从而,对于充分的可移植性,变量c应该被声明为int。

5、例2 在下列程序片段中:

char c;
int i;
long l;
l = (c =i);

i的值被转换为赋值表达式c = i的类型,即char类型。在圆括号中括起来的表达式的值然后被转换为外部赋值表达式的类型,即long int类型。

6、例3 考虑以下程序片段

const char **cpp;
char *p;
const char c = 'A';
cpp = &p; // 违背了约束
*cpp = &c; // 有效
*p = ; // 有效

第一个赋值是不安全的,因为它可能允许以下有效代码企图尝试改变const对象c的值。

6.5.16.2 复合赋值

约束

1、仅对于操作符 += 以及 -=,要么左操作数应该是指向一个完整对象类型的一个原子的、限定的或非限定的指针,并且右操作数应该具有整数类型;要么左操作数应该具有原子的、限定的或非限定的算术类型,且右操作数应该具有算术类型。

2、对于其它操作符,左操作数应该具有原子的、限定的、或非限定的算术类型,并且(考虑在左值转换之后左操作数将会具有的类型)每个操作数应该具有与那些被相应二进制操作符所允许的相一致的算术类型。

语义

3、一个形式为 E1 op= E2复合赋值等价于简单的赋值表达式 E1 = E1 op (E2),除了左值E1仅被计算一次,并且关于一个不确定顺序的函数调用,一个复合赋值的操作是一单个计算。如果E1是一个原子类型,那么复合赋值是一个带有memory_order_seq_cst存储器次序语义的读-修改-写操作。[注:这里,一个指向原子对象的指针可以是一种形式,且E1E2具有整数类型,这个等价于下列代码次序,其中T1E1的类型,T2E2的类型:

T1 *addr = &E1;
T2 val = (E2);
T1 old = *addr;
T1 new;
do
{
new = old op val;
}
while(!atomic_compare_exchange_strong(adds, &old, new));

这里,new作为操作的结果。

如果E1E2具有浮点类型,那么在丢弃的对new的计算期间所遭遇的异常情况或浮点异常应该被丢弃,为了满足对E1 opE2E1 = E1 op (E2)的等价性。比如,如果附录F是有效的,所涉及的浮点类型具有IEC 60559格式,并且FLT_EVAL_METHOD为0,那么等价的代码将会是:

#include <fenv.h>
#pragma STDC FENV_ACCESS ON
/* ... */
fenv_t fenv;
T1 *addr = &E1;
T2 val = E2;
T1 old = *addr;
T1 new;
feholdexcept(&fenv);
for(;;)
{
new = old op val;
if(atomic_compare_exchange_strong(adds, &old, new))
break;
feclearexcept(FE_ALL_EXCEPT);
}
feupdateenv(&fenv);

如果,FLT_EVAL_METHOD不为0,那么T2必须是一个具有E2被计算的范围与精度的类型,为了满足等价性。

ISO/IEC 9899:2011 条款6.5.16——赋值操作符的更多相关文章

  1. ISO/IEC 9899:2011 条款6.5.17——逗号操作符

    6.5.17 逗号操作符 语法 1.expression: assignment-expression expression    ,    assignment-expression 语义 2.一个 ...

  2. ISO/IEC 9899:2011 条款6.5.6——加法操作符

    6.5.6 加法操作符 语法 1.additive-expression: multiplication-expression additive-expression    +    multipli ...

  3. ISO/IEC 9899:2011 条款6.5.4——投射操作符

    6.5.4 投射操作符 语法 1.cast-expression: unary-expression (    type-name    )    cast-expression 约束 2.除非类型名 ...

  4. ISO/IEC 9899:2011 条款6.5.2——后缀操作符

    6.5.2 后缀操作符 语法 1.postfix-expression: primary-expression postfix-expression    [    expression    ] p ...

  5. ISO/IEC 9899:2011 条款6.5.15——条件操作符

    6.5.15 条件操作符 语法 1.conditional-expression: logical-OR-expression logical-OR-expression    ?    expres ...

  6. ISO/IEC 9899:2011 条款6.5.9——相等操作符

    6.5.9 相等操作符 语法 1.equality-expression: relational-expression equality-expression    ==    relational- ...

  7. ISO/IEC 9899:2011 条款6.5.5——乘法操作符

    6.5.5 乘法操作符 语法 1.multiplicative-expression: cast-expression multiplicative-expression    *    cast-e ...

  8. ISO/IEC 9899:2011 条款6.5——表达式

    6.5 表达式 1.一个表达式是操作符与操作数的一个序列,这些操作符与操作数指定了一个值的计算,或指派一个对象或一个函数,或是生成副作用,或执行上述操作的组合.对一个操作符的操作数的值计算顺序排在对该 ...

  9. ISO/IEC 9899:2011 条款3——术语、定义与符号

    3. 术语.定义与符号 1.对于此国际标准的意图,应用了以下定义.其它术语是在用斜体类型或一个语法规则左侧出现的地方定义.在本国际标准中所显式定义的术语不被假定为对其它地方所定义的类似术语的隐式引用. ...

随机推荐

  1. 优化MyEclipse编译速度慢的问题、build、project clean 慢

    优化MyEclipse编译速度慢的问题(重点是1) 1 .关闭MyEclipse的自动validation windows > perferences > myeclipse > v ...

  2. node gyp编译所需要的环境

    安装ms的build工具包,自带python npm install --global --production windows-build-tools

  3. MySQL-linux系统下面的配置文件

    一般linux 上都放在 /etc/my.cnf   ,window 上安装都是默认可能按照上面的路径还是没找到, window 上  可以登录到mysql中  使用   show variables ...

  4. NIO原理详解

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/CharJay_Lin/article/d ...

  5. HiveQL 查询

    一.select ...... from 语句 1.使用正则表达式来指定列 1)从表stocks中选择symbol列和列名以price作为前缀的列 select symbol,`price.*`  f ...

  6. Transformer 比较好的博客

    1. https://www.jianshu.com/p/0c196df57323 细节理解: 2. https://zhuanlan.zhihu.com/p/44121378 3. https:// ...

  7. MAC OS 10.15 挂载ntfs文件系统并设置自动挂载RW模式.

    解决方案 花钱的,省心的 https://www.paragon-software.com/home/ntfs-mac/ 免费的 开源的 https://github.com/osxfuse/osxf ...

  8. Tkinter 之PanedWindow标签

    一.参数说明 参数 作用 background(bg) 设置背景颜色 borderwidth(bd) 设置边框宽度 cursor  指定当鼠标在PanedWindow上飘过的时候的鼠标样式 handl ...

  9. 用avalon框架怎么做轮播图?

    avalon这个框架其实特别的小众,做个轮播图呢?在github上的例子只有一个,而且功能特别的少,有的引入的插件与avalon里面的指令又不兼容,所以找了一个owl-carousel,目前实现了移动 ...

  10. springboot项目获取resource下的文件

    package com.expr.exceldemo; import org.springframework.core.io.ClassPathResource; public class Test ...