---
# System prepended metadata

title: 預處理相關議題
tags: [ISSUE, C4MRTOS]

---

# 預處理相關議題
###### tags: `C4MRTOS` `ISSUE`

## 問題 1 情境 - 嵌套預處理條件
- **#define** 裡面放置 #if #else... 無法編譯
    ```c
    #define M128Executor_lay() { \
      #if USE_EXT0_HWINT        
        Ext0HWInt_lay();        \
      #endif                    
                                \
      #if USE_EXT1_HWINT        
        Ext1HWInt_lay();        \
      #endif.....                
    ```


### 可能解法


### 可能解法測試


### Reference
[The C Preprocessor](https://gcc.gnu.org/onlinedocs/cpp/If.html)
[stackoverflow](https://stackoverflow.com/questions/7246512/ifdef-inside-a-macro)


## 問題 2 情境 - Macro 保護
- **define** 裡放置 do{ }while(0)

### 可能解法

### 可能解法測試

### Reference
[Why use apparently meaningless do-while and if-else statements in macros?](https://stackoverflow.com/questions/154136/why-use-apparently-meaningless-do-while-and-if-else-statements-in-macros)
[多語句macros](https://kezeodsnx.pixnet.net/blog/post/28380463)
[談Linux Kernel巨集 do{…}while(0) 的撰寫方式](https://loda.hala01.com/2017/06/linux-kernel-dowhile0.html)



## 問題 3 情境 - Macro 檢查 (`undefine` or `True` or `False`)
![](https://i.imgur.com/m0LT2cI.png)
```c
// May defined at other file.
// macro condition:
//     1. not defined
//     2. defined and the value is `0` (or say false)
//     3. defined and the value is `not 0` (for example `1`, or say true)
//     4. defined and the value is not a number (for example `a`)
#define ASA

#ifndef ASA
    #define C4M {}
#elif ASA
    #define C4M printf("MVMC\n");
#else
    #define C4M {}
#endif
```

上述程式碼中可能在巨集 `ASA` 定義但沒有給定替代值的情況下發生以下錯誤。
> error: #elif with no expression

### 可能解法
可以參考以下寫法避免 `empty macro` 可能導致的錯誤，
```c
#elif ASA
    #define C4M printf("MVMC\n");
```

改為
```c
#elif (ASA + 0)
    #define C4M printf("MVMC\n");
```

即使在巨集 `ASA` 為 empty 時也能保證 `#elif` 有實際檢查值 (`empty` + 0)

### 可能解法測試
1. 可將原寫法稍作修改
    ```c
    // May defined at other file.
    #define ASA
    
    #ifndef ASA
        #define C4M {}
    #elif (ASA + 0)
        #define C4M printf("MVMC\n");
    #else
        #define C4M {}
    #endif
    ```

2. 或將檢查邏輯重構
    ```c
    // May defined at other file.
    #define ASA 1

    #if defined(ASA) && (ASA + 0)
        #define C4M printf("MVMC\n");
    #else
        #define C4M {}
    #endif
    ```

3. 利用 `#undef` 技巧
    ```c
    // May defined at other file.
    #define ASA 1
    
    #define C4M {}
    #if defined(ASA) && (ASA + 0)
        #undef C4M
        #define C4M printf("MVMC\n");
    #endif
    ```

### Reference
[#ifdef and #if defined](https://blog.csdn.net/hudie86555/article/details/9161249?spm=1001.2101.3001.6650.6&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-6-9161249-blog-102689450.topnsimilarv1&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-6-9161249-blog-102689450.topnsimilarv1&utm_relevant_index=7)
[macro if statement returns error: operator '&&' has no right operand](https://stackoverflow.com/questions/48538243/macro-if-statement-returns-error-operator-has-no-right-operand)
[Test for empty macro definition](https://stackoverflow.com/questions/4102351/test-for-empty-macro-definition)
[Why would one use MACRO+0 !=0](https://stackoverflow.com/questions/37048006/why-would-one-use-macro0-0)


## X Macro (許願筆記整理)
