5 常量检测

在编译时,可以使用 GCC 提供的一个内置函数判断一个值是否是常量。这种信息非常有价值,因为可以构造出能够通过常量叠算constant folding)优化的表达式。__builtin_constant_p 函数用来检测常量。

__builtin_constant_p 的原型如下所示。注意,__builtin_constant_p 并不能检测出所有常量,因为 GCC 不容易证明某些值是否是常量。

int __builtin_constant_p( exp )
 

Linux 相当频繁地使用常量检测。在清单 3 所示的示例中见 ./linux/include/linux/log2.h),使用常量检测优化 roundup_pow_of_two 宏。如果发现表达式是常量,那么就使用可以优化的常量表达式。如果表达式不是常量,就调用另一个宏函数把值向上取整到 2 的幂。

#define roundup_pow_of_two(n) \
( \
__builtin_constant_p(n) ? ( \
(n == 1) ? 1 : \
(1UL << (ilog2((n) - 1) + 1)) \
   ) : \
__roundup_pow_of_two(n) \

6 函数属性

GCC 提供许多函数级属性,可以通过它们向编译器提供更多数据,帮助编译器执行优化。本节描述与功能相关联的一些属性。

属性通过其他符号定义指定了别名。

# define __inline__     __inline__      __attribute__((always_inline))
# define __deprecated           __attribute__((deprecated))
# define __attribute_used__     __attribute__((__used__))
# define __attribute_const__     __attribute__((__const__))
# define __must_check            __attribute__((warn_unused_result))

定义是 GCC 中可用的一些函数属性。它们也是在 Linux 内核中最有用的函数属性。下面解释如何使用这些属性:

always_inline 让 GCC 以内联方式处理指定的函数,无论是否启用了优化。
deprecated 指出函数已经被废弃,不应该再使用。如果试图使用已经废弃的函数,就会收到警告。还可以对类型和变量应用这个属性,促使开发人员尽可能少使用它们。
__used__ 告诉编译器无论 GCC 是否发现这个函数的调用实例,都要使用这个函数。这对于从汇编代码中调用 C 函数有帮助。
__const__ 告诉编译器某个函数是无状态的也就是说,它使用传递给它的参数生成要返回的结果)。
warn_unused_result 让编译器检查所有调用者是否都检查函数的结果。这确保调用者适当地检验函数结果,从而能够适当地处理错误。
下面是在 Linux 内核中使用这些属性的示例。deprecated 示例来自与体系结构无关的内核./linux/kernel/resource.c),const 示例来自 IA64 内核源代码./linux/arch/ia64/kernel/unwind.c)。

int __deprecated __check_region(struct resource 
*parent, unsigned long start, unsigned long n)

static enum unw_register_index __attribute_const__
decode_abreg(unsigned char abreg, int memory)


相关内容

    暂无相关文章