一些C语法回顾
来源:互联网 发布:vm虚拟机下载 for mac 编辑:程序博客网 时间:2024/05/29 10:10
借是累积,故为转载。
1.常数结构体,出现错误提示:incomplete type is not allowed
问:在IIC.c中声明如下:
const struct aa
{
uchar i;
}bb={3};
在IIC.h中声明如下:
extern const struct aa bb;
在main()中这样应用:
uchar cc;
cc = bb.i;
即出现:incomplete type is not allowed的错误提示,不知何解?
答:结构体声明在是不能被extern的,如果多个文件中用了一个同结构体,只想声明一次
需要将结构体在头文件中定义,初始化可以放在.c中,具体如下
//IIC.h
typedef const struct
{
uchar i;
} type_aa;
extern type_aa bb;
//IIC.c
type_aa bb={3};
//main
uchar cc;
void main()
{
cc = bb.i;
}
2. GCC warnings about strict-aliasing
warning: dereferencing type-punned pointer will break strict-aliasing rules
在 gcc 2.x 下编译没有任何 warning 信息的代码换到 gcc 3.x 版本下之后出现了类似的 warning 。原因是 gcc 3 引入了 strict aliasing 架构,当编译时使用了 -fstrict-aliasing 参数(该参数在使用了 -O2 , -O3, -Os 优化参数的情况下默认生效),而源代码中存在一些违反了 strict-aliasing 规则的地方的话,编译器就会对这部分代码提出 warning 。
gcc 3 manual 对于 -fstrict-aliasing 参数的说明是:Allows the compiler to assume the strictest aliasing rules applicable to the language being compiled. For C (and C++), this activates optimizations based on the type of expressions. In particular, an object of one type is assumed never to reside at the same address as an object of a different type, unless the types are almost the same. For example, an "unsigned int" can alias an "int", but not a "void*" or a "double". A character type may alias any other type.
简而言之, 在该参数激活的情况下,编译器希望不同类型的对象不会指向同一个地址。比如像这段代码:
int retLen;someSetFunc((unsigned long*)&retLen);printf("ret len = %d\n",retLen);由于 someSetFunc 的传入参数类型定义为 unsigned long ,所以需要进行这样的指针类型强制 cast 。但对于 -fstrict-aliasing 优化参数来说,这样的转换是有潜在问题的(但实际上可能并不会造成任何问题)。所以如果现有的源代码存在太多这样的类型强制转换的问题的话,对这些代码进行修改也许会是场噩梦。最简单的方法是使用 -fno-strict-aliasing 参数来关闭 gcc 的优化选项,代价是放弃了 strict-aliasing 编译优化可能带来的可执行代码的性能提升。当然也可以用 -Wno-strict-aliasing 来屏蔽相关的 warning 信息,但无论这些 warning 信息多么的无关紧要,总还是“疑似危险”,所以可能的话最好还是把所有的 warning 都消灭掉。
消灭的方法也不算复杂,正如 gcc manual 所示的那样,可以是采用 union 的不同成员变量来完成类型的转换。上面那段代码可以改为:
union u_retLen{int retLen;unsigned long ptr;};someSetFunc(&u_retLen.ptr);printf("ret len = %d\n",u_retLen.retLen);虽然会使源代码变得丑陋,但对于大部分已有的源代码来说,这可能是改动最小的方案了。而对于新写的代码来说,如何更好的设计函数的入口参数(比如使用 void*)可能才是需要去思考的问题了。
3.
- 一些C语法回顾
- 黑马程序员-c语言回顾-基础语法
- Ojbective-C的一些语法
- c的一些基本语法
- 回顾python基本语法
- VHDL语法回顾
- shell语法回顾
- mysql的一些语法和C API
- C 不常见的一些晦涩语法
- 一些C语言语法的细节
- 【C++】C++语法的一些小问题
- C++: #pragma warning的一些语法
- 初学者关于c语法的一些注意事项
- 一些概念回顾
- DIP的一些回顾
- 回顾一些小函数
- C、C++、Java回顾
- flash ActionScript 基本语法回顾
- 跟我一起写 Makefile
- 装载问题
- 设计模式系列之二_责任链模式(Chain of Responsibility)
- C++编程思想读书笔记之 第三章 隐藏实现
- httpclient4.2.2的几个常用方法,登录之后访问页面问题,下载文件
- 一些C语法回顾
- UI -- CorePloty应用指南
- 关于qt的一些小东东
- oracle创建表空间
- SVN commit:remains in tree-conflict错误的解决办法
- float, int , int64计算性能
- VS2008添加GIF资源
- 给phonegap添加一个支持跳转的插件
- Excel has detected that '...xls' is a SYLK file, but can not load it