JavaScript is required to for searching.
跳过导航链接
退出打印视图
Oracle Solaris Studio 12.3:C 用户指南     Oracle Solaris Studio 12.3 Information Library (简体中文)
search filter icon
search icon

文档信息

前言

1.  C 编译器介绍

2.  特定于 C 编译器实现的信息

3.  并行化 C 代码

4.  lint 源代码检验器

5.  基于类型的别名分析

6.  转换为 ISO C

6.1 基本模式

6.1.1 -Xc

6.1.2 -Xa

6.1.3 -Xt

6.1.4 -Xs

6.2 新式函数原型

6.2.1 编写新代码

6.2.2 更新现有代码

6.2.3 混合使用的注意事项

6.3 带有可变参数的函数

6.4 提升:无符号保留与值保留

6.4.1 一些历史背景

6.4.2 编译行为

6.4.3 示例:强制类型转换的使用

6.4.4 示例:相同的结果,不发出警告

6.4.5 整型常量

6.4.6 示例:整形常量

6.5 标记化和预处理

6.5.1 ISO C 转换阶段

6.5.2 旧 C 转换阶段

6.5.3 逻辑源代码行

6.5.4 宏替换

6.5.5 使用字符串

6.5.6 标记粘贴

6.6 const 和 volatile

6.6.1 仅适用于 lvalue 的类型

6.6.2 派生类型中的类型限定符

6.6.3 const 意味着 readonly

6.6.4 const 用法示例

6.6.5 volatile 用法示例

6.7 多字节字符和宽字符

6.7.1 亚洲语言需要多字节字符

6.7.2 编码变化 (Encoding Variations)

6.7.3 宽字符

6.7.4 C 语言特征

6.8 标准头文件和保留名称

6.8.1 标准头文件

6.8.2 保留供实现使用的名称

6.8.3 保留供扩展使用的名称

6.8.4 可安全使用的名称

6.9 国际化

6.9.1 语言环境

6.9.2 setlocale() 函数

6.9.3 更改的函数

6.9.4 新函数

6.10 表达式中的分组和求值

6.10.1 表达式定义

6.10.2 K&R C 重新整理许可证

6.10.3 ISO C 规则

6.10.4 括号用法

6.10.5 As If 规则

6.11 不完全类型

6.11.1 类型

6.11.2 完成不完全类型

6.11.3 声明

6.11.4 表达式

6.11.5 使用原因

6.11.6 示例:不完全类型

6.12 兼容类型和复合类型

6.12.1 多个声明

6.12.2 分别编译兼容性

6.12.3 单编译兼容性

6.12.4 兼容指针类型

6.12.5 兼容数组类型

6.12.6 兼容函数类型

6.12.7 特殊情况

6.12.8 复合类型

7.  转换应用程序以适用于 64 位环境

8.  cscope:交互检查 C 程序

A.  按功能分组的编译器选项

B.  C 编译器选项参考

C.  实现定义的 ISO/IEC C99 行为

D.  C99 的功能

E.  实现定义的 ISO/IEC C90 行为

F.  ISO C 数据表示法

G.  性能调节

H.  Oracle Solaris Studio C:K&R C 与 ISO C 之间的差异

索引

6.6 const 和 volatile

关键字 const 是 ISO C 中包括的 C++ 功能之一。ISO C 委员会创建类似的关键字 volatile 时,创建了“类型限定符”类别。

6.6.1 仅适用于 lvalue 的类型

const 和 volatile 属于标识符的类型,而不属于标识符的存储类。然而,当从表达式求值中获取对象的值时,确切地说是当 lvalue 变为 rvalue 时,经常会将这些类型从类型的最顶端删除。这些术语产生于原型赋值 left-hand-side= right-hand-side,其中左侧必须仍然直接引用对象 (lvalue),右侧仅需要为一个值 (rvalue)。因此,只有本身是 lvalues 的表达式才可以由 const 和/或 volatile 限定。

6.6.2 派生类型中的类型限定符

类型限定符可修改类型名称和派生类型。派生类型是 C 声明的那些可重复应用而生成越来越复杂的类型的部分:指针、数组、函数、结构和联合。除函数之外,可使用一个或两个类型限定符更改派生类型的行为。

以下示例声明并初始化类型为 const int 并且其值未被相应的程序更改的对象。

const int five = 5;

关键字的顺序对于 C 来说不重要。例如,以下声明与第一个示例中的声明在作用上相同:

int const five = 5;
const five = 5;

以下声明用于声明一个类型为指向 const int 的指针的对象,该对象最初指向以前声明的对象。

const int *pci = &five;

指针自身没有限定类型,而是指向一个限定类型。在程序执行过程中几乎可以将指针更改为指向任何 int。除非使用强制类型转换,否则不能使用 pci 修改它所指向的对象,如下例所示:

*(int *)pci = 17;

如果 pci 实际上指向 const 对象,则此代码的行为不确定。

以下声明指示程序中的某位置存在全局对象定义,该对象具有指向 int 的 const 指针类型。

extern int *const cpi;

在此情况下,cpi 的值将不会被相应的程序更改,但是可用来修改它指向的对象。请注意,在该声明中,const 位于 * 之后。以下一对声明产生的效果相同:

typedef int *INT_PTR;
extern const INT_PTR cpi;

这些声明可以合并为以下声明,其中对象的类型声明为指向 const int 的 const 指针:

const int *const cpci;
  

6.6.3 const 意味着 readonly

根据经验,对于关键字,readonly 优于 const。如果某程序以此方式读取 const,则以下示例中的声明很容易理解,即第二个参数仅用于读取字符值,而第一个参数覆盖它指向的字符。

char *strcpy(char *, const char *);

此外,尽管在示例中,cpi 的类型是指向 const int 的指针,但您仍可以通过其他某些方法更改它指向的对象的值,除非它确实指向被声明为 const int 类型的对象。

6.6.4 const 用法示例

const 的两种主要用法是将在编译时初始化的大型信息表声明为无变化,以及指定该指针参数不修改它们所指向的对象。

第一种用法潜在允许某个程序的部分数据被同一程序的其他并行调用共享。它可能导致尝试将此不变数据修改为通过某种内存保护故障立即检测,因为该数据驻留在内存的只读部分中。

第二种用法 const 有助于在生成内存故障之前查找潜在错误。例如,如果将指针传递给无法进行如此修改的字符串,则临时将空字符置入字符串中间的函数会在编译时被检测到.

6.6.5 volatile 用法示例

到目前为止,该示例显示了 const 在概念上较为简单。但是,volatile 到底意味着什么?对于编译器,这意味着访问此类对象时不采用任何代码生成快捷方式。另一方面,ISO C 将声明具有相应特殊属性的每个 volatile 对象指定为程序员的责任。

volatile 对象的四个常见示例为:

前三个示例是具有特殊行为的对象的所有实例: 在程序执行期间的任何点均可修改其值。因此,只要 flag 具有 volatile 限定类型,以下看上去的无效循环将有效。

flag = 1;
while (flag);

某些异步事件将来可能将 flag 设置为零。否则,由于 flag 的值在循环主体中保持不变,编译系统会将以上循环更改为完全忽略 flag 值的真正死循环。

第四个示例涉及调用 setjmp 的函数的局部变量,因此进一步加以讨论。有关 setjmp 和 longjmp 的行为的详细信息指示,与第四种情况匹配的对象的值是不可预测的。对于最需要的行为,longjmp 必须检查调用 setjmp 的函数与调用 longjmp 的函数之间的各个堆栈帧是否有保存的寄存器值。由于存在异步创建堆栈帧的可能性,使该作业更加困难。

在将自动对象声明为 volatile 限定类型时,编译器必须生成与程序员编写的内容完全匹配的代码。因此,此类自动对象的最新值始终保存在内存中,而不是仅保存在寄存器中,且调用 longjmp 时保证为最新。