Nav*_*K N 11 c portability cross-platform compilation
我正在编写一个C程序,预计将与所有主要编译器一起编译.目前我在Linux机器上开发GCC,并在提交代码之前在MSVC上编译.为了使交叉编译变得容易,我正在编译-ansi
和-pedantic
标记.这很有效,直到我开始使用snprintf
C89标准中没有的.GCC可以在没有-ansi
开关的情况下编译它,但MSVC将始终失败,因为它没有C99支持.
所以我做了类似的事情,
#ifdef WIN32
#define snprintf sprintf_s
#endif
Run Code Online (Sandbox Code Playgroud)
这很有效,因为snprintf
并且sprintf_s
具有相同的签名.我想知道这是正确的方法吗?
Dev*_*lar 17
我发现这是在_snprintf()
替代使用时,如果缓冲区溢出保护实际触发,则涉及到问题.从我能够快速浏览的内容看,类似的警告适用于sprintf_s
.
你能看到问题吗?在Linux版本中,输出始终以空值终止.在MSVC中,它不是.
更加微妙的是
size
Linux中的count
参数与MSVC中的参数之间的差异.前者是输出缓冲区的大小,包括终止空值,后者是要存储的最大字符数,排除了终止空值.
哦,不要忘记向Microsoft发送邮件,要求他们支持当前的语言标准.(我知道他们已经宣布他们没有计划支持C99,但无论如何都要打扰他们.他们应得的.)
最重要的是,如果你想发挥它真的安全,你必须为MSVC 提供你自己的snprintf()
(包装_snprintf()
或sprintf_s()
捕捉他们的非标准行为).
eci*_*eci 15
如果你小心,你的建议可以奏效.问题是这两个函数的行为略有不同,如果这对你来说不是问题,你就好了,否则考虑一个包装函数:
MSVC _snprintf
与官方C99(gcc,clang)之间的差异snprintf
:
返回值:
写字节:
有趣的%n
微妙之处:如果您%n
在代码中使用,MSVC会将其保留为单元化!如果由于缓冲区大小很小而停止解析,GCC将始终写入如果缓冲区足够大就会写入的字节数.
所以我的建议是mysnprintf
使用vsnprintf
/ 编写自己的包装函数_vsnprintf
,它给出相同的返回值,并在两个平台上写入相同的字节(注意:%n
更难修复).
pmg*_*pmg -10
不,你的方法注定会失败。
sqrt
并cos
具有相同的原型。您认为可以在程序中交换它们并在更改之前/之后获得相同的行为吗?
您可能应该自己编写snprintf
,或者从互联网下载一个实现(google 是您的朋友)并在 Linux 和 Windows 中使用它。
归档时间: |
|
查看次数: |
21817 次 |
最近记录: |