boost thread warning C4191和algorithm warning C4242

今天抽出時間來整理一下項目中的警告信息,發現有幾個警告很神奇,經過一番查證,終於找到了問題所在。

第一個警告:

boost/thread/win32/thread_primitives.hpp(315): warning C4191: “類型轉換”: 從“boost::detail::win32::farproc_t”到“boost::detail::win32::detail::gettickcount64_t”的不安全轉換
1>          通過結果指針調用該函數可能導致程序失敗

原因:因爲我項目中第三方庫除了boost庫,還引用了cryptopp565這個庫,通過頭文件的逐級追查,發現在cryptopp565的頭文件config.h中有如下定義


#ifdef _MSC_VER
    // 4127: conditional expression is constant
    // 4231: nonstandard extension used : 'extern' before template explicit instantiation
    // 4250: dominance
    // 4251: member needs to have dll-interface
    // 4275: base needs to have dll-interface
    // 4505: unreferenced local function
    // 4512: assignment operator not generated
    // 4660: explicitly instantiating a class that's already implicitly instantiated
    // 4661: no suitable definition provided for explicit template instantiation request
    // 4786: identifer was truncated in debug information
    // 4355: 'this' : used in base member initializer list
    // 4910: '__declspec(dllexport)' and 'extern' are incompatible on an explicit instantiation
#   pragma warning(disable: 4127 4231 4250 4251 4275 4505 4512 4660 4661 4786 4355 4910)
    // Security related, possible defects
    // http://blogs.msdn.com/b/vcblog/archive/2010/12/14/off-by-default-compiler-warnings-in-visual-c.aspx
#   pragma warning(once: 4191 4242 4263 4264 4266 4302 4826 4905 4906 4928)
#endif

正是這裏的pragma warning once釋放了boost的這一警告,一般情況下是被boost屏蔽掉的

 inline detail::gettickcount64_t GetTickCount64_()
            {
                static detail::gettickcount64_t gettickcount64impl;
                if(gettickcount64impl)
                    return gettickcount64impl;

                // GetTickCount and GetModuleHandle are not allowed in the Windows Runtime,
                // and kernel32 isn't used in Windows Phone.
#if BOOST_PLAT_WINDOWS_RUNTIME
                gettickcount64impl = &GetTickCount64;
#else
                farproc_t addr=GetProcAddress(
#if !defined(BOOST_NO_ANSI_APIS)
                    GetModuleHandleA("KERNEL32.DLL"),
#else
                    GetModuleHandleW(L"KERNEL32.DLL"),
#endif
                    "GetTickCount64");
                if(addr)
                    gettickcount64impl=(detail::gettickcount64_t) addr;
                else
                    gettickcount64impl=&GetTickCount64emulation;
#endif
                return gettickcount64impl;
            }

解決辦法:改變頭文件包含順序,先include “boost/thread.hpp”;再include “config.h”;或者換標準庫的thread,不過也奇怪了,std::thread不是從boost::thread搬來的嗎,看樣子並沒有完全照搬,至少實現方法上肯定有差異,改天擼一遍源碼看看

第二個警告:

1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\algorithm(1015): warning C4242: “=”: 從“int”轉換到“char”,可能丟失數據
1>  C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\algorithm(1027): note: 參見對正在編譯的函數 模板 實例化“_OutIt std::_Transform<char*,_OutIt,int(__cdecl *)(int)>(_InIt,_InIt,_OutIt,_Fn1)”的引用
1>          with
1>          [
1>              _OutIt=std::_String_iterator<std::_String_val<std::_Simple_types<char>>>,
1>              _InIt=char *,
1>              _Fn1=int (__cdecl *)(int)
1>          ]
1>  c:\program files\mysql\connector.c++ 1.1\include\cppconn\sqlstring.h(111): note: 參見對正在編譯的函數 模板 實例化“_OutIt std::transform<std::_String_iterator<std::_String_val<std::_Simple_types<char>>>,std::_String_iterator<std::_String_val<std::_Simple_types<char>>>,int(__cdecl *)(int)>(_InIt,_InIt,_OutIt,_Fn1)”的引用
1>          with
1>          [
1>              _OutIt=std::_String_iterator<std::_String_val<std::_Simple_types<char>>>,
1>              _InIt=std::_String_iterator<std::_String_val<std::_Simple_types<char>>>,
1>              _Fn1=int (__cdecl *)(int)
1>          ]

原因:起初我以爲是mysql connector中 sqlstring封裝的問題,後來發現也是上邊pragma warning once的問題,它打開了4242報警,不過不得不吐槽mysql connector c++封裝的不那麼如人意(目前考慮換下純c的接口)…

解決辦法:修改頭文件順序

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章