How to C in 2016

Declare variable in any block

Not

void test(uint8_t input) {
    uint32_t b;

    if (input > 3) {
        return;
    }

    b = input;
}

But

void test(uint8_t input) {
    if (input > 3) {
        return;
    }

    uint32_t b = input;
}

For counter variable

Not

uint32_t i;

    for (i = 0; i < 10; i++)

But

for (uint32_t i = 0; i < 10; i++)

Array initialization

Not

uint32_t numbers[64];
    memset(numbers, 0, sizeof(numbers));

But

uint32_t numbers[64] = {0};

Structure initialization

Not

struct thing {
        uint64_t index;
        uint32_t counter;
    };

    struct thing localThing;

    void initThing(void) {
        memset(&localThing, 0, sizeof(localThing));
    }

But

struct thing {
        uint64_t index;
        uint32_t counter;
    };

    struct thing localThing = {0};

Function input type

Not

void processAddBytesOverflow(uint8_t *bytes, uint32_t len) {
    for (uint32_t i = 0; i < len; i++) {
        bytes[0] += bytes[i];
    }
}

But

void processAddBytesOverflow(void *input, uint32_t len) {
    uint8_t *bytes = input;

    for (uint32_t i = 0; i < len; i++) {
        bytes[0] += bytes[i];
    }
}

將輸入型別設定為 void 並在內容中重新指派

Return Type

若回傳值有「是」/「否」這種需求,建議引入 stdbool.h 函式庫,使用 true 或 false 來代替整數型態(例如 int32_t)的 1 或 0。讓程式更容易閱讀。

可以的話,建議創一個 enum 來表示複合型態的回傳型別。例如:

typedef enum growthResult {
    GROWTH_RESULT_SUCCESS = 1, // 成功
    GROWTH_RESULT_FAILURE_GROW_NOT_NECESSARY, // 失敗 1
    GROWTH_RESULT_FAILURE_ALLOCATION_FAILED   // 失敗 2
} growthResult;

Coding style

寫作習慣

程式沒人看得懂,功能再怎麼強都沒用。文章中建議使用自動格式工具(auto code formatter):clang-format。

例如要對目標 main.c 進行轉換,在終端機中敲入:

$ clang-format -style="{BasedOnStyle: llvm, IndentWidth: 4, AllowShortFunctionsOnASingleLine: None, KeepEmptyLinesAtTheStartOfBlocks: false}" "$@" -i main.c

clang-format 會將將程式依建議重新排版。但是每次都這樣敲太麻煩了。可以將 clang-format 指令以 alias 的型式建在 .bash_profie 或 .bash_rc 中:

# .bash_profile or .bash_rc

alias clang-format='clang-format -style="{BasedOnStyle: llvm, IndentWidth: 4, AllowShortFunctionsOnASingleLine: None, KeepEmptyLinesAtTheStartOfBlocks: false}" "$@"'

之後就能直接以 clang-format 進行轉換:

$ clang-format -i main.c

其中若省略掉 -i 是直接在 bash 中預覽結果,而不將轉換結果覆寫掉目標檔案。

Allocation

Not malloc bu calloc, and prevent memset

Last updated