如果已定义,则使用#(_DEBUG)
Use of #if defined(_DEBUG)
我正在编写一个基于C++MFC的应用程序。偶尔我会添加#if defined(_DEBUG)语句,以便在开发过程中对我有所帮助。我的经理要求我删除所有这样的语句,因为他不想要两个版本的代码。我的感觉是,如果没有使用#if defined(_DEBUG)的能力,漏洞更有可能在开发过程中悄悄出现而未被发现。
其他人对此有什么想法吗?
好吧,运行库和MFC有两个版本,调试和发布,所以总是有两个代码版本。
使用#ifdef(_DEBUG)和assert()将在调试过程中帮助您。
但是。。。
不建议在#ifdef子句中添加类/结构成员,因为对象的二进制接口将不同,如果从调试和发布版本序列化或发送这样的结构,它们将不同。
E.G:
#include <assert.h>
class MyClass
{
void SetA(int a)
{
assert(a<10000); // this is recommended
}
#ifdef _DEBUG
int m_debugCounter; // This is not recommended
#endif
};
在本例中,sizeof(MyClass)与调试和发布版本不同。
使用生产代码编译调试代码有优缺点。
一些优点:
- 生产可执行文件将更小
- 准备从未使用过的日志消息、统计信息等时不会浪费资源
- 如果外部库仅由调试代码使用,则可以删除它们的依赖项
一些缺点:
- 您最终会得到两个不同的可执行文件
- 由于某些调试日志在生产版本中不可用,这使得现场故障排除更加困难
- 存在两个版本的行为不相同的风险。例如,错误可能出现在生产版本中,但在测试过程中没有出现,因为测试是在调试版本中完成的
- 两个版本之间存在不兼容的风险,例如文件格式略有不同(如Erab的回答所示)
特别是,如果使用编译出来的代码(甚至是assert()调用),请非常小心,调试代码没有副作用。否则,当调试打开时,您将创建消失的错误。
通过使用一个不错的日志框架,您至少可以获得一些优势。例如,我在使用rLog方面取得了一些成功——我喜欢它的一点是它经过了优化,可以最大限度地减少休眠日志记录语句的开销。其他最新的日志记录框架也提供了类似的功能。
话虽如此,我使用过的每个C++环境都至少有一定级别的编译入/编译出调试代码。例如,assert()是根据NDEBUG宏编译的。ASSERT()/DEBUG似乎是MSVC在该主题上的一个特定变体(尽管据我所知,MSVC也支持更标准的ASSERT()/NEDEBUG)。
如果经理想要这样,他不理解目标代码质量。。。如果#If应该删除,您也可以删除任何类型的资产。因为他们只是隐藏#if_DEBUG。请记住,MFC和CRT本身充满了这个(真正的)有用的#if_DEBUG代码!
如果没有这样特殊的_DEBUG块,我就无法针对类的滥用,也无法捕获内部问题。
- 在提升multi_index容器中,是否定义了"default index"?
- #定义c-预处理器常量..我做错了什么
- 用C++中的一个变量定义一个常量
- 部分定义/别名模板模板参数
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- #为""定义宏;静态";针对不同的上下文
- 如何确保C++函数在定义之前声明(如override关键字)
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 当类在C++中定义时,有什么方法可以"register"类吗?
- 在命名空间中定义函数还是限定函数
- 此代码是否违反一个定义规则
- 编译C++时未定义的引用
- 不同翻译单元中不可重载的非内联函数定义
- 为什么在定义函数之前先声明它
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 在类定义之后定义一个私有方法
- 使用用户定义函数的字符串反转
- 用户定义函数中的指针和输入
- 在Visual Studio代码中定义DEBUG和RELEASE符号
- C++中是否已经有一些类可以打印到 cout,但在未定义某些宏时可以关闭(例如 DEBUG)