我们有一个用C编写的代码,有时候不能很好地处理零指针。
代码最初是在Solaris上编写的,这样的指针会导致分段错误。不理想,但比耕作更好。
我们的经验是,如果从AIX上的空指针读取,则得到0.如果使用 xlc 编译器,则可以添加选项-qcheck=all
来捕获这些指针。但我们使用gcc(并希望继续使用该编译器)。 gcc 是否提供此类选项?
答案 0 :(得分:6)
gcc是否提供了这样的选项?
我怯懦地自愿回答不,它没有。虽然我不能引用关于gcc和运行时NULL检查的缺席信息。
你要解决的问题是你试图在一个编写得不好的程序中对未定义的行为进行更多的定义。
我建议您咬紧牙关并切换到xlc或手动将NULL
检查添加到代码中,直到找到并删除了错误行为。
考虑:
删除错误后,您可以开始删除这些检查。
答案 1 :(得分:3)
请帮助我们,并为您的代码添加适当的NULL
支票。通过仅在需要时检查NULL
而不是让编译器在任何地方执行检查,您不仅可以略微提高性能,而且您的代码将更易于移植到其他平台。
我们没有提到这样一个事实,即您将更有可能打印出正确的错误消息,而不是让编译器丢弃一些难以理解的堆栈转储/源代码位置/错误代码,这些代码根本无法帮助您的用户。
AIX使用NULL页面的概念。实质上,NULL
(即虚拟地址0x0
)被映射到包含一大堆零的位置。这允许字符串操作代码e.t.c.尽管遇到NULL
指针仍然继续。
这与大多数其他类Unix系统相反,但它并没有违反C标准,后者认为解除引用NULL是未定义的操作。但是,在我看来,这是非常糟糕的:它需要一个会剧烈崩溃的应用程序,并将其变成一个无声地忽略编程错误的应用程序,可能会产生完全错误的结果。
据我所知,GCC无法解决根本破坏的代码问题。即使是历史上支持的模式,例如可写字符串文字,也在较新的GCC版本中逐渐被淘汰。
在使用-fmudflap
等内存调试选项时可能会有一些支持,但我真的不知道 - 在任何情况下都不应该在生产系统中使用调试代码,尤其是强制破坏代码才能工作。
底线:我认为您不能避免添加明确的NULL
支票。
不幸的是我们现在提出了一个基本问题:应该在哪里添加NULL检查?。我想让编译器不加选择地添加这样的检查会有所帮助,只要你在发现问题时添加一个明确的检查。
不幸的是,没有Valgrind对AIX的支持。如果你有现金,你可能想看看IBM Rational Purify Plus for AIX - 它可能会发现这样的错误。
也可以在测试系统上使用xlc
,在其他所有内容上使用gcc
,但遗憾的是它们并不完全兼容。