解決Visual Studio 2010/2012的RC4011 warnings

千里馬肝發表於2013-09-12

如果在vc10/11工程的rc檔案中有以下任意一行程式碼:

#include <winuser.h>
#include <richedit.h>

那麼vc將會給出一對警告:

C:\Program Files\Microsoft Visual Studio 10.0\VC\include\string.h(54): warning RC4011: identifier truncated to '_CRT_SECURE_CPP_OVERLOAD_STANDA'
C:\Program Files\Microsoft Visual Studio 10.0\VC\include\string.h(76): warning RC4011: identifier truncated to '_CRT_SECURE_CPP_OVERLOAD_SECURE'

其原因是vc提供了一個巨集_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_MEMORY,用來自動將程式碼中的memcpy替換成memcpy_s。
memcpy_s在被提出時,確實感覺這樣子程式碼是安全了,但是兩個函式的引數不一致,導致修改量上去了,而且移植性也沒有了,於是vc好心地提供這個巨集用來自動替換。
那麼為什麼會有上面的警告呢?

問題出在RC,也就是resource compiler,基於歷史原因,它會自動將長度超過31的巨集截斷,應該是RC只用了char[32]來存諸的緣故,於是我們就看到讓人不舒服的警告了。

解決辦法很簡單:

針對#include <winuser.h>,將其替換為<windows.h>。

針對#include <richedit.h>,稍微麻煩一點。
據我們所知,rc包含.h的目的通常只是為了一些#define,對其中的函式神馬的並不在意。
那麼如警告中描述所示,問題是出在string.h,同時我們包含richedit其實也只是為了得到RICHEDIT_CLASS,那麼事情好辦了,修改如下:

#ifdef RC_INVOKED
#define _INC_STRING
#endif

#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
#include "resource.h"

如MSDN中所描述:

To conditionally compile your code with the RC compiler, surround code that RC cannot compile with #ifndef RC_INVOKED and #endif.

而string.h中是這樣定義的:

#pragma once

#ifndef _INC_STRING
#define _INC_STRING

...

#endif

好的,你懂的,我就不多說什麼了。

:D

 

相關文章