Major/minor macros in FreeBSD/Linux
剛剛寫了一個簡單至極的小程式,是的,就是那個第一千次 commit 的 class,::mmi::util::version。這個 class 把三個 uint32_t 包起來,分別賦予 major version number、minor version number 以及 revision number 這三個意義。可是,想 porting 回 GCC 時,竟然產生 compilation error。錯誤訊息是這個樣子的:
c++ -Wall -I./include -g `env PKG_CONFIG_PATH=. pkg-config --define-variable=prefix=. --cflags libMMI` -o src/mmi/util/version.o -c src/mmi/util/version.cpp
src/mmi/util/version.cpp:72: error: expected unqualified-id before '(' token
src/mmi/util/version.cpp:72: error: abstract declarator `uint32_t' used as declaration
src/mmi/util/version.cpp:72: error: `uint32_t mmi::util::version::$_12' is not a static member of `class mmi::util::version'
src/mmi/util/version.cpp:72: error: expected primary-expression before "int"
src/mmi/util/version.cpp:72: error: expected `)' before "int"
src/mmi/util/version.cpp:102: error: expected `,' or `;' before '}' token
*** Error code 1
而出錯的函式長這樣:
uint32_t version::major() const
{
return major_;
}
這真是令人費解,在 MSVC++6 上面沒什麼問題,程式也簡單到不行,為什麼換到 GCC 上就出了問題了呢?仔細檢查之後,發現在錯誤訊息裡有這麼一行:
src/mmi/util/version.cpp:72: error: `uint32_t mmi::util::version::$_12' is not a static member of `class mmi::util::version'
函式名字從 major() 變成詭異的 $_12 了,於是猜測是 macro 的問題,major 和 minor 被 #define 成某個奇怪的東西了。果不其然,在 FreeBSD 5 下找到 /usr/include/sys/types.h 裡的這段程式:
#ifndef _KERNEL /* * minor() gives a cookie instead of an index since we don't want to * change the meanings of bits 0-15 or waste time and space shifting * bits 16-31 for devices that don't use them. */ #define major(x) ((int)(((u_int)(x) >> 8)&0xff)) /* major number */ #define minor(x) ((int)((x)&0xffff00ff)) /* minor number */ #endif /* !_KERNEL */
而我需要的 <algorithm> 裡面又輾轉 #include 到了這個檔案,於是產生了這個奇怪的問題。解決方法很簡單,把函式名字改成 major_version()、minor_version() 與 revision_number() 即可。
檢查了一下 Linux,在 Redhat 7 下的 /usr/include/sys/sysmacros.h 也有同樣的 macros。原來不僅 MSVC++6 會笨到把 max/min 給 #define 成自己的東西,連 FreeBSD/Linux 也會幹這種鳥事。
One Backlink
make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/root/download/Programs/pcmanx-pure-gtk2-0.3.3' make: *** [all] Error 2 [root@finleyhost pcmanx-pure-gtk2-0.3.3]# 根據錯誤訊息找到這篇說明http://www.jeffhung.net/blog/articles/jeffhung/257/ 如他所言是#define 的問題 而將某個function替換成奇怪的字串 在 /usr/include/libintl.h :40 extern char *gettext (__const char *__msgid) __THROW; 而剛好在/usr/include/glib-2.0/glib/gi18n.h 和
Post a Comment