英锐恩单片机论坛,Microchip单片机,模拟器件,接口电路,麦肯单片机,单片机应用交流

 找回密码
 立即注册
搜索
电子烟方案单片机单片机开发深圳单片机开发
单片机方案国产单片机8位单片机电子烟方案开发
查看: 4325|回复: 0
打印 上一主题 下一主题

MPLAB C30 与ANSI C 的差别(二)关键字的区别

[复制链接]
跳转到指定楼层
1#
发表于 2009-4-18 18:10:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
2.3.2 指定函数的属性
在MPLAB C30 中,可以对程序中调用的函数进行某些声明,帮助编译器优化函数调
用,且更准确地检查代码。
关键字_attribute_ 允许在声明时指定特殊的属性。关键字后面紧跟双括弧中的属
性说明。目前支持函数的下列属性:
· address (addr)
· alias ("target")
· const
· deprecated
· far
· format (archetype, string-index, first-to-check)
· format_arg (string-index)
· near
· no_instrument_function
·noload
· noreturn
· section ("section-name")
· shadow
· unused
· weak
我们也可以通过在关键字前后使用__ (双下划线)来指定属性(例如,用
__shadow __ 代替shadow)。这样使得在头文件中使用它们时不必考虑会出现与宏
同名的情况。
我们要想在声明中指定多个属性,可以在双括弧内使用逗号将属性分隔开,或者在一
个属性声明后紧跟另一个属性声明。
address (addr)
address 属性为函数指定绝对地址。这个属性不能与section 属性同时使用;
address 属性优先。
void foo() __attribute__ ((address(0x100))) {
...
}
alias ("target")
alias 属性为另一个符号声明一个别名,必须指定这个符号。
使用这一属性会产生对对象的外部引用,必须在链接时解析该引用。

const
许多函数除了检查自身的参数外不会检查任何其他值,只会影响其返回值。可像算术
运算符一样,对这种函数进行公共子表达式删除和循环优化。这些函数应该用属性
const 来声明。例如:
int square (int) __attribute__ ((const int));
也就是说,上述假设的square 函数的实际被调用次数即使比程序指定的次数少一些
也是安全的。
应该注意,如果函数有指针参数,且检查指针指向的数据,那么这种函数一定不能用
const 声明。同样,调用非const 函数的函数通常也不能声明为const。具有void 返
回值类型的const 函数没有什么意义。
deprecated
关于deprecated 属性的信息,请参阅第2.3.1 节“指定变量的属性” 。
far
far 属性告知编译器不应该用更有效的调用指令形式来调用该函数。
format (archetype, string-index, first-to-check)
format 属性指定一个函数具有printf、scanf 或strftime 类型参数,要根据格式
字符串检查这些参数的类型。例如,考虑以下声明:
extern int
my_printf (void *my_object, const char *my_format, ...)
__attribute__ ((format (printf, 2, 3)));
以上语句使编译器检查对my_printf 调用中的参数,确定是否与printf 类型的格
式字符串参数my_format 一致。
参数archetype 确定如何解释格式字符串,应该为printf、scanf 或strftime
之一。参数string-index 指定哪个参数是格式字符串参数(参数从左至右编号,
从1 开始), first-to-check 指定根据格式字符串检查的第一个参数的编号。对于
不能检查参数的函数(如vprintf),指定第三个参数为0。这种情况下,编译器仅
检查格式字符串的一致性。
在上面的例子中,格式字符串(my_format)是函数my_print 的第二个参数,从
第三个参数开始检查,所以format 属性的正确参数是2 和3。
format 属性允许识别以格式字符串作为参数的用户自定义函数,所以MPLAB C30 可
以检查对这些函数的调用有无错误。每当要求这种警告(使用-Wformat)时,编译
器总会检查ANSI 库函数printf、fprintf、sprintf、scanf、fscanf、
sscanf、strftime、vprintf、vfprintf 和vsprintf 的格式,所以不必修改
头文件stdio.h。
format_arg (string-index)
format_arg 属性指定一个函数具有printf 或者scanf 类型的参数,修改这个函
数(如将它翻译为另外一种语言),并把函数的结果传递给printf 或scanf 类型的
函数。例如,考虑以下声明:
extern char *
my_dgettext (char *my_domain, const char *my_format)
__attribute__ ((format_arg (2)));
上述语句使编译器检查对函数my_dgettext 的调用中的参数,该函数的结果传递给
printf、scanf 或strftime 类型函数,确定是否与printf 类型的格式字符串参
数my_format 一致。
参数string-index 指定哪个参数是格式字符串参数(从1 开始)。
format-arg 属性允许识别修改格式字符串的用户定义函数,所以MPLAB C30 可以
检查对printf、scanf 或strftime 函数的调用,这些函数的操作数是对用户定义
函数的调用。
near
near 属性告知编译器可以使用call 指令的更有效形式调用函数。
no_instrument_function
如果指定命令行选项-finstrument-functions,那么几乎所有用户函数的入口和
出口处在编译时都会被插入profiling 函数。而函数被指定此选项时将不执行上述操作。
noload
noload 属性指明应该为函数分配空间,但不应把实际代码装入存储器。如果应用程序
设计为在运行时将函数装入存储器(如从EEPROM),这一属性很有用。
void bar() __attribute__ ((noload)) {
...
}
noreturn
一些标准库函数是不能返回的,例如abort 和exit。MPLAB C30 自动清楚这种情
况。有些程序自定义了不会返回的函数,我们可以将这些函数声明为noreturn 来告
知编译器这种情况。
void fatal (int i) __attribute__ ((noreturn));
void
fatal (int i)
{
/* Print error message. */
exit (1);
}
noreturn 关键字告知编译器fatal 不会返回。这可以优化代码,而不必考虑如果
fatal 返回会怎样。这可以在某种程度上优化代码。而且这样有助于避免未初始化变
量的假警告。
对于noreturn 函数,非void 的返回值类型并没有什么意义。
section ("section-name")
通常,编译器将生成的代码存放在.text 段中。但有时可能需要其他的段,或者需要
将某些函数存放在特殊的段中。Section 属性指定将一个函数存放在特定的段中。例
如下面的声明:
extern void foobar (void)
__attribute__ ((section (".libtext")));
上述语句将函数foobar 存放在.libtext 段中。
section 属性与address 属性有冲突。忽略段名会导致警告。
shadow
shadow 属性使编译器使用影子寄存器而不是软件堆栈来保存寄存器。该属性通常与
interrupt 属性同时使用。
void __attribute__ ((interrupt, shadow)) _T1Interrupt (void)
interrupt [ ( [ save(list) ] [, irq(irqid) ]
[, altirq(altirqid)] [, preprologue(asm) ]
) ]
使用这个选项来指明指定的函数是一个中断服务程序。当指定该属性时,编译器将生
成适合在中断服务程序中使用的函数prologue 和epilogue 序列。可选参数save
指定在函数prologue 和epilogue 中各自要保存和恢复的一系列变量。可选参数
irg 和altirg 指定要使用的中断向量表ID。可选参数preprologue 指定要在编译
器生成的prologue 代码前生成的汇编代码。完整描述和例子,参见第7 章“中
断”。
unused
这个函数属性,表明函数可能不会被使用。MPLAB C30 不会为这种函数发出未使用函
数的警告。
weak
关于weak 属性,参见第2.3.1 节“指定变量的属性”。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|公司首页|Microchip单片机,模拟器件,接口电路,麦肯单片机,单片机应用交流 ( 粤ICP备09008620号 )

GMT+8, 2024-5-2 11:37 , Processed in 0.052087 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表