多行宏定義中的註釋問題

轉載自:http://mylovejsj.blog.163.com/blog/static/3867397520085302748722/

早上在寫代碼時遇到這樣一個問題:即如何在一個擁有多行的宏定義中做註釋?,這裏把方法演化的過程貼出來,可能對某些朋友有些借鑑意義。


宏定義高深莫測,而且是比較細節的東西,詳細說明請參見"C參考手冊"之類的書籍。

在我的代碼中,我大致要做這樣一個簡單的事情:printf("%s%s%s\n", "hello", "macro", "yeah!"); "%s%s%s\n"這個字符串中每一項輸出都有一定的含義,而且在真實代碼裏,這個串中的輸出項可不止3個,所以一個直接的想法就是將其定義爲一個宏。

#define STR_OUTPUT_FORMAT_V0  "%s%s%s\n"
printf(STR_OUTPUT_FORMAT_V0, "hello ", "macro, ", "yeah!");
程序輸出:hello macro, yeah!

由於真實代碼中這個串很長,所以打算美化一下格式,定義成下面的樣子:
#define STR_OUTPUT_FORMAT_V1  "%s\
                               %s\
                               %s\n"
printf(STR_OUTPUT_FORMAT_V1, "hello ", "macro, ", "yeah!");
程序輸出:hello                                macro,                                yeah!

這樣的定義顯然不對,也在我意料之中,續行符將空格也續到格式串中了,導致輸出的結果中帶有大量空格。

改進一下,利用C語言的字符串自動連接語法。
#define STR_OUTPUT_FORMAT_V2  "%s"\
                              "%s"\
                              "%s\n"
printf(STR_OUTPUT_FORMAT_V2, "hello ", "macro, ", "yeah!");
程序輸出:hello macro, yeah! 

現在的問題是如何在這樣一個多行的宏定義里加入註釋,字段含義特殊,加上註釋有利於以後維護以及別人閱讀你的代碼,否則一堆%s%s,讓人看了就頭痛。先這麼加試試:
#define STR_OUTPUT_FORMAT_E1  "%s"\   /* comment1 */
                              "%s"\   /* comment2 */
                              "%s\n"  /* comment3 */
printf(STR_OUTPUT_FORMAT_E1, "hello ", "macro, ", "yeah!");
我們得到的結果:編譯錯誤。
通過gcc -E 選項我們看到,宏替換後的代碼: 
                              "%s"\
                              "%s\n"
int main() {
        printf("%s"\, "hello ", "macro, ", "yeah!");
}

由於沒有續行符在註釋前面,所以宏定義的後兩行實際上並沒有被包含在宏定義中,就像沒有暫住證的人一樣,被GCC這個"警察"逮個正着。

繼續改進:
#define STR_OUTPUT_FORMAT_V3  "%s"   /* comment1 */ \
                              "%s"   /* comment2 */ \
                              "%s\n"  /* comment3 */
printf(STR_OUTPUT_FORMAT_V3, "hello ", "macro, ", "yeah!");
程序輸出:hello macro, yeah! 
顯然預編譯器忽略宏定義中的註釋以及空格,STR_OUTPUT_FORMAT_V3就完全符合我的要求了。

當然,很多人不建議使用宏,特別是C++的Fans,宏也的確有很多弊端,這裏也有替代方法:
const char *str_output_format = "%s"    /* comment1 */
                                 "%s"    /* comment2 */
                                 "%s\n"; /* comment3 */
printf(str_output_format, "hello ", "macro, ", "yeah!");
程序輸出:hello macro, yeah! 

用一個字符串變量代替格式宏,還可以避免上述由於在宏中做註釋帶來的一系列問題
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章