作者 主題: 請教各位關於 C 程式中使用 Macro 的時候,如果我們有多行的情況  (閱讀 10755 次)

0 會員 與 1 訪客 正在閱讀本文。

shanchieh

  • 可愛的小學生
  • *
  • 文章數: 14
    • 檢視個人資料
Greeting ,
請教各位關於 C 程式中使用 Macro 的時候,如果我們有多行的情況。例如:
代碼: [選擇]

#define InitializeQueueHeader(QueueHeader)              \
{                                                       \
    (QueueHeader)->Head = (QueueHeader)->Tail = NULL;   \
    (QueueHeader)->Number = 0;                          \
}


但是我使用 Embedded Linux C 的編譯器,卻會認為那是錯誤的語法。而出現錯誤訊息,請問是不是我在編譯的時候,有遺漏一些參數呢?印象中樣使用某些的標準,在編譯的時候要加入 -std=gnu99 這類的參數。

上面的 Macro ,如果我改寫成一行。編譯就沒有問題了。

PS : 我用的編譯器是我們自己為我們的板子Porting 的。版本是:
gcc version 2.95.2

謝謝您。

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
把\號移到每一列的最後一個字元試看看(中間不要有空白)
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

shanchieh

  • 可愛的小學生
  • *
  • 文章數: 14
    • 檢視個人資料
引述: "stlee"
把\號移到每一列的最後一個字元試看看(中間不要有空白)


謝謝您的指點。修改成您的方式,可是依然會有錯誤的訊息。我目前整與 Porting toolchain 的人員聯繫。希望能解決這樣的問題,不然手邊有數千行的程式,很多都是這樣的用法。如果不能使用此方式。就很頭大了。

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
那那那......改成一般函數來呼叫不要用巨集替換可以嗎???
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
#define AAA 123
每個顏色中間最少都要有一個空白應該就可以成立了

多出來的空白或少掉的空白....沒試過(因為過不了編譯器)
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
代碼: [選擇]

#define AAA InitializeQueueHeader(QueueHeader)\
{\
(QueueHeader)->Head = (QueueHeader)->Tail = NULL;\
(QueueHeader)->Number = 0;\
}


是不是改成這樣的???(不要縮排喔???很像也可以縮排,忘記了....以前用過要查一下)

一定要有AAA不然是拿InitializeQueueHeader(QueueHeader)替換成一個"沒有頭"的函數,您不覺得很怪嗎?_?
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

twu2

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 5396
  • 性別: 男
    • 檢視個人資料
    • http://blog.teatime.com.tw/1
引述: "stlee"
一定要有AAA不然是拿InitializeQueueHeader(QueueHeader)替換成一個"沒有頭"的函數,您不覺得很怪嗎?_?


您要不要找本 C 的書好好的再讀一下呢? 您的說法才比較奇怪吧.

而且... C 本來就是 free style 的語言, 關空白字元什麼事呢? 如果有那個 C Compiler 會因為語法之間多出的空白造成問題... 那有問題的一定是那個 compiler, 而不會是那個這樣子寫的程式.

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
代碼: [選擇]

#define InitializeQueueHeader(QueueHeader)              \
{                                                       \
    (QueueHeader)->Head = (QueueHeader)->Tail = NULL;   \
    (QueueHeader)->Number = 0;                          \
}

可是這樣替換出來不就變成
代碼: [選擇]

main()
{
  InitializeQueueHeader(QueueHeader)
}

變成
main()
{

{                                                      
    (QueueHeader)->Head = (QueueHeader)->Tail = NULL;  
    (QueueHeader)->Number = 0;                          
}

}


小弟是覺得怪在這?_?
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

twu2

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 5396
  • 性別: 男
    • 檢視個人資料
    • http://blog.teatime.com.tw/1
怪? 是有那兒不符合 C 的語法嗎? 你不會這樣子用, 不代表 C 不能這樣子用.
建議找本 C 的書來看吧.

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
嗯....可以這樣用喔....看來真的還需要在修練了

謝謝指教!!!謝謝
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

twu2

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 5396
  • 性別: 男
    • 檢視個人資料
    • http://blog.teatime.com.tw/1
至於樓主的問題, 先用 cpp 把程式轉換看會不會有問題或轉出來的內容正不正確吧.

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
嗯....這種寫法應該滿陷阱的,會讓主程式不太好寫>"<
(我還是用比較笨的寫法吧^^!)

呵呵...謝謝twu2大教了一課
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
看到了,問題應該會在分號

如果按這種寫法的話,正確的應該要這樣
代碼: [選擇]

main()
{
  InitializeQueueHeader(QueueHeader)
}

但一般會寫成
代碼: [選擇]

main()
{
  InitializeQueueHeader(QueueHeader);
}

多了一個分號

這樣對不對呢???
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
可是這樣也是個怪.....參數該怎麼傳呢?????

InitializeQueueHeader(QueueHeader) 的QueueHeader????

可是下面的
(QueueHeader)->Head = (QueueHeader)->Tail = NULL;  
(QueueHeader)->Number = 0;

又很像可令其通順....頭大中@@!
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

twu2

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 5396
  • 性別: 男
    • 檢視個人資料
    • http://blog.teatime.com.tw/1
stlee 兄請去把 C 前置處理程式 (C Preprocessor) 與 "巨集" (macro) 研究一下吧. 你就會知道你的問題本來就不會是個問題.

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
還真的沒去研究過這方面的(前置替換與巨集)

最多拿來當做傳回值的常數替換等簡單工作......

以後還請twu2大不吝指教喔....謝謝您
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

shanchieh

  • 可愛的小學生
  • *
  • 文章數: 14
    • 檢視個人資料
感謝各位的熱心回覆與參與,這是我們公司自己的 RISC CPU 的 Toolchain,不是一般大多人使用的 ARM 等... 此 Toolchain 使我們另一組人 porting 的,版本是:gcc 2.95.2 。

因為我在正在 porting 一些驅動程式,例如 WiFi(RT2561) 等。這些程式都大量使用 Macro ,其他的驅動程式也是。如果要全部改寫。可能是滿辛苦的。我在另一個討論區中,有網友說這大多是 Toolchain 的問題,問我為何不用 2.95.3 或者3.X 版。會比較穩定。

關於這方面的問題,我已經在與 Porting toolchain 的人員討論。如有任何的結果與答案,我在與各位分享。

謝謝各位。

PS : 有問題的 macro 在 ARM9, 一般 Linux 的 gcc 等編譯器都是編譯的,我想程式的寫法是沒有問題,我已經在 ARM9, CentOS, Debian 等平台都成功編譯、移植了。就是我們公司的 toolchain 不行。