| 語言 | 建議 | 原因 |
|---|---|---|
| C (C89/C99/C11/C17/C23) | 不轉型 | void* 隱式轉換為任意指標,轉型反而掩蓋 <stdlib.h> 遺漏錯誤 |
| C++ (C++98 至今) | 必須轉型 | void* 不隱式轉換,需 static_cast<T*>(malloc(...)) 或改用 new |
若未包含 <stdlib.h>,編譯器假設 malloc 回傳 int:
int *p = malloc(10); // 警告:int 指標指派
int *p = (int*)malloc(10); // 強制轉型「消除」警告,但錯誤依然存在!
轉型掩蓋了「遺漏標頭檔」這個嚴重錯誤,導致 64 位元系統指標截斷災難。
-Wimplicit-function-declaration 預設開啟,會報錯誤而非警告/* C 語言標準寫法 */
#include <stdlib.h>
int *p = malloc(10 * sizeof *p); // sizeof *p 自動適應型別變更
if (!p) { /* 處理失敗 */ }
/* C++ 現代寫法 */
#include <memory>
auto p = std::make_unique<int[]>(10); // RAII,自動釋放
// 或
int *p = static_cast<int*>(malloc(10 * sizeof *p));
| 迷思 | 事實 |
|---|---|
| 轉型能提高可讀性 | 型別已在宣告處可見,轉型屬贅述 |
| C++ 相容需轉型 | 若需雙語言編譯,用巨集包裝而非直接轉型 |
| 舊教材都轉型 | K&R 二版(1988)即建議不轉型,舊習慣源自 C89 前 |
/* 共用標頭檔 alloc.h */
#ifdef __cplusplus
#define ALLOC(type, n) static_cast(malloc((n) * sizeof(type)))
#else
#define ALLOC(type, n) malloc((n) * sizeof(type))
#endif
/* 使用 */
int *p = ALLOC(int, 10);
但最佳做法:C 用 malloc/free、C++ 用 new/delete 或智慧指標,不要混用。