JavaScript is required to for searching.
跳过导航链接
退出打印视图
Oracle Solaris Studio 12.2:C 用户指南
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.4.7 第三个示例:整型常量

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 constvolatile

6.6.1 类型(仅适用于 lvalue

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

6.6.3 const 意味着 readonly

6.6.4 const 用法示例

6.6.5 volatile 意味着精确语义

6.6.6 volatile 用法示例

6.7 多字节字符和宽字符

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

6.7.2 编码变种

6.7.3 宽字符

6.7.4 转换函数

6.7.5 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.  K&R Solaris Studio C 与 Solaris Studio ISO C 之间的差异

索引

6.6 constvolatile

关键字 const 是 C++ 的特征之一,它与 ISO C 是共通的。随着 ISO C 委员会发明了关键字 volatile,“类型限定符”类别应运而生。

6.6.1 类型(仅适用于 lvalue

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

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

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

例如,

const int five = 5;

声明并初始化类型为 const int 并且其值未被相应的程序更改的对象。关键字的顺序对于 C 并不重要。例如,声明:

int const five = 5;

const five = 5;

与以上声明在效果上相同。

声明

const int *pci = &five;

声明一个类型为指向 const int 的指针的对象,该对象最初指向以前声明的对象。指针本身没有限定类型-它指向限定类型,在程序执行过程中几乎可以更改为指向任何 int。除非使用强制类型转换,否则不能使用 pci 修改它所指向的对象,如下所示:

*(int *)pci = 17;

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

声明

extern int *const cpi;

表明程序中某个位置存在类型为指向 intconst 指针的全局对象的定义。在此情况下,cpi 的值将不会被相应的程序更改,但是可用来修改它指向的对象。请注意,在以上声明中,const 位于 * 之后。以下一对声明产生的效果相同:

typedef int *INT_PTR;
extern const INT_PTR cpi;

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

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

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

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

6.6.5 volatile 意味着精确语义

到目前为止,示例均使用了 const,因为它在概念上较为简单。但是,volatile 到底意味着什么?对于编译器编写者,它只有一种含义: 访问此类对象时不采用代码生成快捷方式。在 ISO C 中,声明具有相应属性及 volatile 限定类型的各个对象是程序员的责任。

6.6.6 volatile 用法示例

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

前三个示例是具有特殊行为的对象的所有实例: 在程序执行期间的任何点均可修改其值。因此,表面上的死循环:

flag = 1;
while (flag);

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

第四个示例涉及调用 setjmp 的函数的局部变量,因此进一步加以讨论。关于 setjmplongjmp 行为的细小字体注释表明对于符合第四种情形的对象的值没有任何保证。对于大多数所期望的行为,有必要让 longjmp 检查调用 setjmp 的函数与调用 longjmp 的函数之间的各个栈帧是否有保存的寄存器值。由于存在异步创建栈帧的可能性,使该作业更加困难。

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