快要下班的時候,開發部的一名小鮮肉找我幫忙解決一個問題:
才哥,我們提供給計費組的庫在計費主機上編譯報錯了,但是提供給其他組用時沒有編譯報錯。計費也不認,說編譯器報的是我們代碼上的錯誤,要我解決,幫我看看呢,這是報錯信息:
pbobject.h:129: error: reference to 'Message' is ambiguous
message.h:169: error: candidates are: class google::protobuf::Message
Message.h:28: error: class Bmco::Message
pbobject.h:129: error: reference to 'Message' is ambiguous
message.h:169: error: candidates are: class google::protobuf::Message
Message.h:28: error: class Bmco::Message
pbobject.h:129: error: 'Message' has not been declared
我一看是模糊定義,是二義性問題,大概有了譜。
最開始的想法是找到編譯報錯的cpp文件,使用g++ -E選項把編譯轉換單元展開看看到底是哪里重復定義了。但是由於計費組的make輸出太復雜太長,看不出來。於是直接在計費的代碼目錄下使用find命令全文搜索了“class Message”,發現果真有一個類定義。但是有一個問題是開發部這邊使用的protocol buffer下面的Message應該是要用名字空間“google::protobuf” 來限定訪問,不應該有這樣的問題,於是查看了開發部提供的.h文件 赫然有一個“using namespace google::protobuf”,於是謎底揭開了,還是開發部這邊提供的頭文件問題,為什么其他組沒有遇到問題?那是運氣好,別人沒有定義全局的Message類。
解決辦法就是讓開發部的小鮮肉把頭文件的using namespace google::protobuf去掉,把所有函數參數,對象,指針定義Message的地方通過顯示的名字空間訪問。
總的來說還是開發部的代碼不規范,既然是要提供庫給其他模塊,那么首先就應該定義一個屬於開發部這邊的名字空間,所有要提供出去的名稱都在這個名字空間下來聲明。 名字空間就是專門來解決這種問題的,這種錯誤不應該犯。
