等等! ——这个问题并不像听起来那么愚蠢。标题很简洁。
我有一些调试代码来验证数据结构的正确性,还有一些断言来检查此正确性,我只想在调试版本中启用它们:
{$ifdef DEBUG}
function Sorted : Boolean;
function LinearSearchByValue(const T : TType) : NativeInt;
{$endif}
以及稍后的方法:
assert(Sorted);
例如。
在启用断言的调试版本中,一切都很好。但是,在我的发布版本中,断言被禁用,行 assert(Sorted);
导致编译器错误E2003 Undeclared identifier: 'Sorted'
。完全正确,标识符没有声明,但是断言也被关闭,不应该被评估或生成任何代码。 (尝试通过声明方法来欺骗断言,但没有实现会导致正常错误“不满足前向或外部声明”。它显然也在寻找方法主体。)
这会导致一些困惑的代码,其中根本不应该存在于发布版本中的方法必须声明并具有主体,以便编译断言,而断言已关闭。
在 Delphi 2010 中,如何声明仅存在于调试版本中的方法,并在断言中使用那些也应仅存在于调试版本中的方法?
更多信息:
我尝试用
{$ifopt C+}
包装方法声明,它检查断言是否已打开。调用assert
仍然因“未声明的标识符”而失败。编译器选项肯定是断言被关闭。 (我检查过:))
我已尝试将调用包装到
assert
使用这些方法{$ifdef DEBUG}
。然而,这很困惑并且不应该是必需的。有一次,它让我担心即使在发布版本中也会编译断言,并且出于性能原因我根本不需要它们。 (这没有发生 - 未生成断言代码。)我当前的策略是始终声明这些方法,但在发布版本中 ifdef 方法主体出来并用虚拟结果填充它。这里的目标是编译所有断言,但方法的开销尽可能小,并且它们的返回值(如果它们实际上在发布版本中被调用)显然是错误的。
里>Delphi 中是否有与 C/C++ 样式宏等效的宏,其中
ASSERT(x)
宏在发布版本中会被简单地定义为空,导致编译器既看不到也不关心断言内的语句?这是在 C++ 中使用宏的少数干净方法 (IMO) 之一。
因此,虽然未生成断言,但它们已被编译。这又回到了我的问题:如何最好地混合仅调试方法和断言以及发布版本?
最佳答案
不要从您的发布版本中排除该代码。将代码保留在那里,并无条件编译它。
您反对将代码存在于发布版本中的论点是它“困惑”。但代码你已经写好了,所以无论编译与否都会很乱。你不妨让编译器来编译它;毕竟,编译额外的代码并不会花费更长的时间。
尝试排除与断言相关的代码只会因为需要条件编译指令而使您的代码变得更困惑。
断言和调试信息是正交设置。当不进行调试时可以启用断言,反之亦然。
另一种方法是将与断言相关的代码移至单元测试中。然后,它们会自动从您的应用程序的所有版本中排除,但仍可用于测试。
关于delphi - 如何在发布版本中编译依赖于仅调试代码的assert()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15748192/