凡是都有规矩,没有规矩就不成方圆,为了让自己写的代码更具可读性,一致性,移植性更好,所以一定要遵循特定的coding convention,由于使用EFI 代码的缘故,所以本文的coding convention大多数参考intel EFI driver writer’s guide的
1缩进(Indentation and Line Length)
有些风格使用tab建,有些使用空格键,使用空格键有的缩进4个,有的缩进2个,EFI中为了显示更多的字符在一行中,且在嵌套很多的情况下任然能够显示很多内容,所以统一采用2个缩进,鉴于不同的编译器对tab键的设置不一样,有的是4个字符,有的是8个,所以为了保持一致性统一不用tab进行缩进。
2注释规则
(1)在文件首一般进行文档的说明用一下格式
/*++
Module Name:
Abstract:
--*/
(2)
函数中的注释
EFI_STATUS
Foo (
IN UINTN Arg1,
IN UINTN Arg2
)
/*++
Routine Description:
<<description>>
Arguments:
<<argument names and purposes>>
Returns:
<<description of possible return values>>
--*/
{
}
(3)内部注释
//
//This is an example comment for the next code line
//
3命名规则
(1)目录和文件名
一般的命名规则
变量的命名规则非常重要,研究表明平均10-16个字母的命名规则是最容易除错的,但是重点是命名要能够传达一个清晰的代替意思。
命名一般是以每个首字母大写的单词组成例如:ThisIsAnExampleOfWhatToDoForPci,这个命名。
(2)函数名和变量名
函数名和变量名也按照一般的命名规则来,即首字母大写后面字母小写。
(3)匈牙利表示法在EFI中不做推荐。唯一的使用是在全局变量,和模块变量中。
匈牙利表示法是一种命名约定,由Charles Simonyi发明。他把变量的类型(或者它的预期使用)等信息编码在变量名中。在某些圈子里,它被极度热爱,而在另一些地方,它又受到严厉的批评。它的主要优势在于变量名就说明了它的类型或者用法。它的主要缺点在于类型信息并不值得放在变量名中。
(4)全局变量和模块变量
例如
gThisIsAGlobalVariableName
mThisIsAModuleVariableName
(5)宏名
以Macros,#define,typedef声明的全部用大写,每个单词之间用下划线‘-’隔开。
宏中尽量用圆括号将顺序标注清楚
(6)枚举,结构体联合
枚举结构体联合的命名方式和,函数名和变量名也按照一般的命名规则来,即首字母大写后面字母小写。
typedef enum {
EnumMemberOne,
EnumMemberTwo,
EnumMemberMax
} ENUMERATED_TYPE;
typedef struct {
UINT32 FieldOne;
UINT32 FieldTwo;
UINT32 FieldThree;
} MY_STRUCTURE;
typedef union {
UINT16 Integer;
CHAR16 Character;
} MY_UNION;
(7)include file
#inndef and #define #endif,文件名和.H文件名得对应关系是例如:SerialDriver.H 对应的为 _SERIAL_DRIVER_H_.
(8)竖直对应关系
推荐使用一行一个声明,
(9)水平位置
注意空格的使用
4子函数格式
1 子函数
//
// Function Prototype Declaration
//
EFI_STATUS
EFIAPI
FooName (
IN UINTN Arg1,
IN UINTN Arg2, OPTIONAL
OUT UINTN *Arg3,
IN OUT UINTN *Arg4
);
//
// Function Implementaion
//
EFI_STATUS
EFIAPI
FooName (
IN UINTN Arg1,
IN UINTN Arg2, OPTIONAL
OUT UINTN *Arg3,
IN OUT UINTN *Arg4
)
/*++
Routine Description:
<<description>>
Arguments:
<<argument names and purposes>>
Returns:
<<description of possible return values>>
--*/
{
UINTN LocalOne;
UINTN LocalTwo;
UINTN LocalThree;
. . .
}
(2)
Call 子函数
//
// Function and arguments fit on a single line
//
Foo (A, B, C);
//
// Function and arguments do not fit on a single line
//
Status = BlockIo->ReadBlocks (
BlockIo,
MediaId,
Lba,
BufferSize,
Buffer
);
(3)布尔表达式
布尔变量,布尔值不需要具体的和True or FALSE 比较,非布尔变量,布尔值需要通过(==, !=, >, <, >=, <=).进行比较。指针需要和NULL进行比较,例如:
BOOLEAN Done;
UINTN Index;
VOID *Ptr;
if (Index != 0) {
if (Index == 0) {
if (Done )
if (!Done )
if (Ptr != NULL) {
if (Ptr == NULL) {
(4)条件表达式
//
// IF construct
//
if (A > B) {
IamTheCode ();
}
//
// IF / ELSE construct
//
if (Pointer == NULL) {
IamTheCode ();
} else {
IamTheCode ();
}
//
// IF / ELSE IF / ELSE construct
//
if (Done == TRUE) {
IamTheCode();
} else if (A < B) {
IamTheCode();
} else {
IamTheCode();
}
//
// Nested IF construct
//
if (A > 10) {
if (A > 20) {
IamTheCode ();
} else {
if (A == 15) {
IamTheCode ();
} else {
IamTheCode ();
}
}
}
(5)循环表达式
//
// WHILE Loop construct
//
while (Pointer != NULL) {
IamTheCode();
}
//
// DO Loop construct
//
do {
IamTheCode();
} while (A < B);
//
// FOR Loop construct
//
for (Index = 0; Index < MAX_INDEX; Index++) {
IamTheCode(Index);
}
//
// Nested Loop construct
//
for (Column = 0; Column < MAX_COLUMN; Column++) {
for (Ror = 0; Row < MAX_ROW; Row++) {
IamTheCode(Index);
}
}
(6)switch表达式
switch (Variable) {
case 1:
IamTheCode ();
break;
case 2:
IamTheCode ();
break;
default:
IamTheCode ();
break;
}
(7)Goto表达式
{
EFI_STATUS Status;
. . .
Status = IAmTheCode ();
if (EFI_ERROR (Status)) {
goto ErrorExit;
}
IDoTheWork ();
ErrorExit:
. . .
return Status;
}