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. 思想家:潘石屹学python

    1.python在一些算法,图像处理,机器视觉方面越来越重要 2.计算机语言像英语一样,渐渐成为一种非专业技术,不能成为专业,而只能成为一种工具 3.想发挥工具价值,需要与别的专业结合,例如潘总的房地 ...

  2. dt6.0之mip改造-img正则替换mip-img

    最近没事,打算把自己的小项目改造为mip,进行测试学习,想把资讯栏目:http://zhimo.yuanzhumuban.cc/news/.全部改造为mip.但是MIP改造一项是:图片标签的改造.而且 ...

  3. “只有DBA才能导入由其他DBA导出的文件”各种解决办法

    “只有DBA才能导入由其他DBA导出的文件”各种解决办法 当oracle导入的时候出现“只有 DBA 才能导入由其他 DBA 导出的文件”的时候通常有以下几种解决办法! 1:常见的是直接grant   ...

  4. 安装 selenium 对于python而言属于一个第三方的模块

    针对第三方的模块,如何安装 在dos界面输入python -m pip install 模块名称 安装相关的浏览器以及浏览器的驱动 下载谷歌浏览器的驱动,淘宝镜像 下载后,解压,然后将得到的exe文件 ...

  5. ElementUI入门和NodeJS环境搭建

    1. ElementUI简介 我们学习VUE,知道它的核心思想式组件和数据驱动,但是每一个组件都需要自己编写模板,样式,添加事件,数据等是非常麻烦的,   所以饿了吗推出了基于VUE2.0的组件库,它 ...

  6. H3CNE学习5 STP

    一.STP 1.概念 2.STP开机默认会运行 二.STP操作 1.原理 2.根桥选举,首先比前面的ID,谁小谁就是根桥,如果ID一样就比较mac,谁小谁就是根桥 可以手动修改优先级,图中可以将swA ...

  7. Spring入门(二)——DI

    1. DI Dependency Injection,依赖注入.当对象里有属性或对象的时候,就需要为这些属性或对象赋值 2. 流程 这里介绍两种方式 set方法 注解方式 2.1 set方法 Bean ...

  8. 使用socket.io实现多房间通信聊天室

    websocket的实现有很多种,像ws和socket.io,这里使用的是socket.io来实现多房间的效果. 这里的使用没有使用socket.io官方提供的namespace和room,而是完全通 ...

  9. 表述数据的手段——json

    一.JSON 语法规则 在 JS 语言中,一切都是对象.因此,任何支持的类型都可以通过 JSON 来表示,例如字符串.数字.对象.数组等.但是对象和数组是比较特殊且常用的两种类型: 对象表示为键值对 ...

  10. cf 1037D BFS

    $des$一个 n 个点 m 条边的无向连通图从 1 号点开始 bfs,可能得到的 bfs 序有很多,取决于出边的访问顺序.现在给出一个 1 到 n 的排列,判断是否可能是一个 bfs 序. $sol ...