【发布时间】:2014-07-21 00:59:35
【问题描述】:
我正在使用 C++11 的 static_assert 来执行编译时检查,以防止使用不安全的函数,和/或在应该使用新功能并且相关 API 不可用时向用户提供反馈日期(例如使用std::strftime、std::to_string等)。
如果任何源代码尝试使用过时的功能,我想强制失败,但我需要它是完全跨平台的,并且还绕过或解决其他“助手”,例如微软自己的弃用。
我发现在使用 gnu 工具链时可以使用 .sections,我可以在 OpenBSD 的 cdefs.h (http://ninjalj.blogspot.co.uk/2011/11/your-own-linker-warnings-using-gnu.html) 中看到它的定义,但我没有与 Visual Studio 等效的东西。
例如,我可以使用下面的代码来防止strcpy/strcat:
# define COMPILE_TIME_CHECK(expression, message) static_assert(expression, message)
# define GUARANTEE_FAILURE (0 == 1)
# define DISABLED_FUNCTIONS_MESSAGE_CSTRING "strcpy, strcat must be replaced with strlcpy and strlcat, respectively"
# define strcat COMPILE_TIME_CHECK(GUARANTEE_FAILURE, DISABLED_FUNCTIONS_MESSAGE_CSTRING);
它可能不干净但有效;但问题是当你试图对其他玩得不太好的人做同样的事情时,比如ctime和localtime:
_CRT_INSECURE_DEPRECATE(localtime_s) static __inline struct tm * __CRTDECL localtime(const time_t * _Time)
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\time.inl(86): error C2059: syntax error : 'static_assert'
有没有一种方法可以阻止特定功能(警告或编译失败),同时提供一条消息说明在它们的位置使用什么,而不会以合适的方式与 gcc/visual studio 发生冲突? Visual Studio 中的 CRT 宏无法通过上述定义防止上述错误。
我不相信像 __declspec(deprecated) int strcpy(char*,char*);(如此处所述:C++ mark as deprecated)这样的东西会一直发挥作用,而且比仅仅为函数名称设置定义需要更多的工作和更少的描述性。
【问题讨论】:
-
最低 Visual Studio 2012 和 GCC 4.8(几乎来自体面的 C++11 支持)
-
VS2012 缺乏像样的 C++11 支持。考虑 2013 年?
-
从错误中可以看出,我已经在使用 2013 - 无论如何它不能解决我的可用选择。
标签: c++ visual-studio gcc c++11 cross-platform