凡是都有規矩,沒有規矩就不成方圓,爲了讓自己寫的代碼更具可讀性,一致性,移植性更好,所以一定要遵循特定的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;
}