ISO/IEC 9899:2011 条款6.5.16——赋值操作符

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 = 0;      // 有效

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

6.5.16.2 复合赋值

约束

1、

时间: 2024-10-15 12:52:56

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

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

6.5.4 投射操作符 语法 1.cast-expression: unary-expression (    type-name    )    cast-expression 约束 2.除非类型名指定了一个void类型,否则该类型名应该指定原子的.限定的,或非限定的标量类型,并且操作数应该具有标量类型. 3.涉及到指针的转换,而不是由6.5.16.1所允许的限制,应该用一个显式的投射来指定. 4.一个指针类型不应该被转换为任一浮点类型.一个浮点类型不应该被转换为任一指针类型. 语义 5.在一

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

6.5.5 乘法操作符 语法 1.multiplicative-expression: cast-expression multiplicative-expression    *    cast-expression multiplicative-expression    /    cast-expression multiplicative-expression    %    cast-expression 约束 2.每个操作数应该具有算术类型.% 操作符的操作数应该具有整数类型. 语义

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

6.5.2 后缀操作符 语法 1.postfix-expression: primary-expression postfix-expression    [    expression    ] postfix-expression    (    argument-expression-listopt    ) postfix-expression    .    identifier postfix-expression    ->    identifier postfix-expres

ISO/IEC 9899:2011 条款6.4.3——通用字符名

6.4.3 通用字符名 语法 1.通用字符名: universal_character-name: \u hex-quad(四位十六进制数) \U hex-quad hex-quad hex-quad: hexadecimal-digit    hexadecimal-digit    hexadecimal-digit    hexadecimal-digit 约束 2.一个通用字符名不应该指定一个字符,其短标识符比00A0要小,除了0024($),0040(@),0060(`)之外,也不应该

ISO/IEC 9899:2011 条款6.5.1——基本表达式

6.5.1 基本表达式 语法 1.primary-expression: identifier constant string-literal (    expression    ) generic-selection 语义 2.一个标识符是一个基本表达式,提供为,它作为指派一个对象(在这种情况下,它是一个左值)或一个函数(在这种情况下,它是一个函数指派符)而被声明.[注:从而,一个未声明的标识符是对此语法的违反.][译者注:比如: int a = 10; a; // 这是一个基本表达式 ]

ISO/IEC 9899:2011 条款5——5.2.1 字符集

5.2.1 字符集 1.两个字符集和它们相关联的依次顺序应该被定义:写在源文件中的集合(源字符集),以及在执行环境中被解释的集合(执行字符集).每个集合此外被划分为一个基本字符集,其内容由本子条款给出,以及一组零个或多个区域特定的成员(这些不是基本字符集的成员),称为扩展字符.这些成员结合起来也被称为扩展字符集.执行字符集的成员的值是由实现定义的.

ISO/IEC 9899:2011 条款6——语言

6 语言 6.1 标记法 1.在本条款中所使用的语法标记法.语义类别(非终结符)用斜体字指示,而字面量单词以及字符集成员(终结符)用粗体字指示.跟在一个非终结符后面的冒号(:)引出其定义.在单独的行中列出可替换的定义,除了当用单词“之一”开头时.一个可选的符号用下标“opt”来指示,这样 { expressionopt } 指示一个在大括号中包裹的可选的表达式. 2.当在文本中引用了语义类别时,它们不用斜体标明并且单词用空格而不是连接号(-)来分隔. 3.在附录A中给出了语言语法的概述. 6.2

ISO/IEC 9899:2011 条款5——5.2.4 环境限制

5.2.4 环境限制 1.翻译与执行环境都约束了语言翻译器和库的实现.下面概述了对一个顺应标准实现的语言相关的环境限制:库相关的限制在条款7中讨论. 5.2.4.1 翻译限制 1.实现应该能够翻译并执行至少一个程序,该程序包含以下每个限制的至少一个实例:[注:实现应该尽量避免强加使用固定的翻译限制.] —— 127个语句块的嵌套层级 —— 63个带条件的包含嵌套层级 —— 12个指针.数组与函数声明符(以任意结合)在一个声明中用于修饰一个算术.结构体.联合体或void类型. —— 63个圆括号包

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

6.5 表达式 1.一个表达式是操作符与操作数的一个序列,这些操作符与操作数指定了一个值的计算,或指派一个对象或一个函数,或是生成副作用,或执行上述操作的组合.对一个操作符的操作数的值计算顺序排在对该操作符的结果的值计算之前.[译者注:比如 int a = (100 + 5) * (20 - 6); 对于上述表达式,就对于当中的 * 操作符而言,先计算乘法操作符左右两边的操作数的计算,最后再计算乘法操作结果. ] 2.如果在一个标量对象上的副作用相对于同一标量对象上的另一个不同副作用或是使用同一