首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C99 可變參數宏 __VA_ARGS__ 實戰:調試日志開關與 Android NDK 應用

     編輯:關於C語言

C99 可變參數宏 __VA_ARGS__ 實戰:調試日志開關與 Android NDK 應用

C99 引入宏可變參數 ... 與 __VA_ARGS__,GCC 另支持 args... 寫法。配合 ## 連接符可實現參數可選。

基本語法

// 標準寫法
#define LOG(fmt, ...) fprintf(stdout, fmt, __VA_ARGS__)
// GCC 擴展
#define LOG(fmt, args...) fprintf(stdout, fmt, args)
// 允許省略可變參數(## 吞噬前導逗號)
#define LOG(fmt, ...) fprintf(stdout, fmt, ##__VA_ARGS__)

調試日志開關模式

#ifdef DEBUG
#define LOG(fmt, ...) fprintf(stdout, ">>>>>" fmt "<<<<", ##__VA_ARGS__)
#else
#define LOG(fmt, ...)  // 空展開,零開銷
#endif

// 使用
LOG("init: %d\n", 42);
// 編譯:gcc -DDEBUG test.c → 輸出 ">>>>>init: 42<<<<"
// 不加 -DDEBUG → 無任何代碼生成

Android NDK 實戰

// Android.mk
LOCAL_LDLIBS := -llog
LOCAL_CFLAGS += -DDEBUG

// NDKTest.cpp
#include <android/log.h>
#define LOG_TAG "HelloNDK"
#ifdef DEBUG
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#else
#define LOGI(...) do{}while(0)
#define LOGD(...) do{}while(0)
#define LOGE(...) do{}while(0)
#endif

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
    LOGI("JNI_OnLoad");
    // ...
}

關鍵技巧

  • do{}while(0):空宏安全塊,防止 if (...) LOG(...); else ... 語法錯誤。
  • ##__VA_ARGS__:當可變參數為空時吞噬前導逗號,避免 fmt, 語法錯誤。
  • 編譯器標誌 -DDEBUG 控制日志編入,發布版零開銷。

可變參數宏是構建類 printf 靈活日志系統的核心技術,廣泛用於嵌入式、移動端、高性能服務端。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved