良好的代碼應**符合讀者的通用認知**,而非混雜語言實現細節。以「會話 ID 存儲」為例,展示如何透過調整常量定義,消除 C 語言「字串以 \0 結尾」特性對業務邏輯的滲透。
#define SESSION_ID_LEN_MAX 256
char g_SessionId[SESSION_ID_LEN_MAX];
int save_session_id(char *_id, int _len) {
if (_len < 1 || _len > SESSION_ID_LEN_MAX) return ERROR; // Bug:等於 MAX 時寫越界
memcpy(g_SessionId, _id, _len);
g_SessionId[_len] = '\0';
return SUCCESS;
}
當 _len == 256,g_SessionId[256] = '\0' 寫入第 257 位元組 → **緩衝區溢出**。
if (_len < 1 || _len >= SESSION_ID_LEN_MAX) return ERROR; // 邏輯正確但語意違和
**問題**:通用認知中「最大值」應為**有效取值**。讀者看到 >= 必須停下思考:「為何最大值不可用?」→ 查看陣列定義 → 理解「留位給 \0」→ 增加認知負荷,維護風險增大。
#define SESSION_ID_LEN_MAX 255 // 業務層面的真實最大長度(不含 \0)
char g_SessionId[SESSION_ID_LEN_MAX + 1]; // +1 內部消化 C 語言 \0 特性
int save_session_id(char *_id, int _len) {
if (_len < 1 || _len > SESSION_ID_LEN_MAX) return ERROR; // 邏輯與認知一致
memcpy(g_SessionId, _id, _len);
g_SessionId[_len] = '\0';
return SUCCESS;
}
**站在「不懂編程語言特性」的角度寫代碼。** 將「語言實現細節」(\0 結尾、陣列下標從 0 開始、整數溢出等)封裝在定義層,暴露給業務邏輯的純粹是**領域概念**(長度、容量、狀態)。不同語言混雜(編程語言 + 自然語言)是可讀性、可維護性殺手。
#define BUF_SIZE 1024; char buf[BUF_SIZE + 1];#define MAX_PAYLOAD 1460; uint8_t frame[MAX_PAYLOAD + HEADER_SIZE];本文出自「至簡李雲」博客。