在函数声明中,包括参数名及其数据类型。尽管 C 语言并未要求参数名,但在 linux 中,选择这么做。因为对读者而言,这是增加值信息的一种简单方式。

         在函数声明中不要使用 extern 关键字,因为这会增加声明行的长度,且严格来说也没有必要。

         当声明函数时,请保持元素顺序的规律性。例如,用这个函数声明作例子说明:

__init void * __must_check action(enum magic value, size_t size, u8 count,

                                  char *fmt, ...) __printf(4, 5) __malloc;

一个函数声明首选的元素顺序是:

●       存储类(storage class)(见下文:static __always_inline;注意,__always_inline 从技术上讲是一个属性,但被视为 inline 处理 ),存储类说明符决定了链接属性和函数可见性。与变量不同——变量利用存储类来管理内存位置和生命周期——函数始终具有全局生命周期。因此,当存储类应用于函数声明时,它仅决定了程序的哪些部分可以访问并调用该函数。函数声明只有两种有效的存储类,即extern (外链接,整个程序的任何代码可访问,默认均为此存储类)和 static(内链接,仅其被声明的源文件内的代码可访问和调用)

●       存储类属性(storage class attribute) (在本例中为 __init ,即段声明,但也包括像 __cold 这样的东西 ),实际上这是一个gcc属性:

#define __init      __section(.init.text) __cold notrace

# define __section(S) __attribute__ ((__section__(#S)))

●       返回类型(在本例中为 void * )

●       返回类型属性(在本例中为 __must_check )

●       函数名(在本例中为 action )

●       函数参数(在本例中为 enum magic value, size_t size, u8 count, char *fmt, ... ) ,注意,应当总是包括参数名。

●       函数参数属性(在本例中为 __printf(4, 5)   ),__printf 用于指定接收printf风格参数的函数。

●       函数行为属性( 在本例中为 __malloc )

注意,对于函数定义(即,实际函数体 ) ,编译器不允许函数参数之后出现函数参数属性。在这些情况下,它们应当跟在存储类属性之后(例如,注意下述 __printf(4, 5) 相比于上述函数声明的位置变化):

static __always_inline __init __printf(4, 5) void * __must_check action(enum magic value,size_t size, u8 count, char *fmt, ...) __malloc

{

       ...

}

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐