理论上讲,这些过期函数的确不安全,或者说容易被不安全地调用。微软也很「贴心」地在编译器的报错信息中给出了解决方案,比如用 strcpy_s 和 InetPton 来替换,都不用你去搜解决办法了。所以按照我的习惯,一般是就地解决掉这些问题再往下走。
不过呢,可能有的人性子比较急,也有的时候是从旧项目移植,想快点编译完先跑一下看看效果。改代码毕竟要时间,从 strcpy 改成 strcpy_s 可能还好,而从 inet_addr 改到 InetPton 就真的没有想象中那么轻松。所以编译器也给出了另一种建议,你可以设上几个 Macro,SDL 也是可以被忽略的。
到此为止都还比较和谐,大家都是有商有量地做事情。然而当我腾出时间准备把过期函数扫扫干净,把同事临时加的 Macro 去掉之后一编译,问题来了——SDL 这次怎么不报错了?
再三确认过 vcxproj 中已经没有了相关的 Macro,并且 SDL 的确是打开了。但这次编译就是不会报错,似乎对我面前的 strcpy 视而不见。为什么呢?
Google 上搜了一大圈也没有方向。最后还是被我排除法硬试出来的——平台工具集如果选了 v120_xp,那么 SDL 即使打开,有些过期函数也不会报错。是不是 SDL 就此失效,我不清楚,因为我没法去覆盖所有的过期函数。我估计,微软是这样想的:你既然打算让这个程序跑在过期的 OS 上,那函数过期不过期已经不重要了。
其实还有一个更重要的原因:strcpy_s 还好,但要是把 inet_addr 真的换成了 InetPton,你就会发现在 WinXP 下你的程序根本就跑不起来。实际上,WinXP 就不支持 InetPton。MSDN 上的信息表明,最低也要 Vista 才可以。
我们的程序暂时还不能抛弃 WinXP 用户,但若要完全不知道用了哪些过期函数我又心有不甘,于是我打算做一个 #if……#else……#endif 来解决这个过期 OS 兼容的问题。搜了一下,正确的姿势应该是:
#if (_WIN32_WINNT >= 0x602)最后我是在 Debug 版本上用了平台工具集 v120,在 Release 时还是用了 v120_xp。过期函数只会局限在以上 Macro 范围内,有限度地使用。
#else
#endif
另外,WinXP 也不支持条件变量 CONDITION_VARIABLE,所以这个服役期超长的操作系统是真的应该淘汰了。我不得不说一句:WannaCry,干得好!
没有评论:
发表评论