Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;调试由变量控制的宏 我正在编写一个C++程序,我尝试包括一个由宏控制的调试消息方法,它只在创建调试方法的对象时在运行时设置调试标志时调用。性能很重要,因此我尝试在不需要的情况下不调用调试消息传递代码,而不是编译两个不同版本的程序,一个带有调试宏,另一个没有调试宏_C++_Debugging_Variables_Macros - Fatal编程技术网

C++;调试由变量控制的宏 我正在编写一个C++程序,我尝试包括一个由宏控制的调试消息方法,它只在创建调试方法的对象时在运行时设置调试标志时调用。性能很重要,因此我尝试在不需要的情况下不调用调试消息传递代码,而不是编译两个不同版本的程序,一个带有调试宏,另一个没有调试宏

C++;调试由变量控制的宏 我正在编写一个C++程序,我尝试包括一个由宏控制的调试消息方法,它只在创建调试方法的对象时在运行时设置调试标志时调用。性能很重要,因此我尝试在不需要的情况下不调用调试消息传递代码,而不是编译两个不同版本的程序,一个带有调试宏,另一个没有调试宏,c++,debugging,variables,macros,C++,Debugging,Variables,Macros,直到现在,我一直在尝试这样的事情: unsigned int flag = 0xFFFFFFFF; if (flag != 0) { #define DEBUG } #ifdef DEBUG debug("This is call 1 to the debug method"); #endif #ifdef DEBUG debug("This is call 2 to the debug method"); #endif debug(std::string

直到现在,我一直在尝试这样的事情:

unsigned int flag = 0xFFFFFFFF;

if (flag != 0)
{
    #define DEBUG
}

#ifdef DEBUG
     debug("This is call 1 to the debug method");
#endif

#ifdef DEBUG
    debug("This is call 2 to the debug method");
#endif



debug(std::string message) 
{
    if ((flag && MASK_I_DEFINED_SOMEWHERE_FOR_STUFF) != 0)
    {
         std::cout << message << std::endl;
    }
}
但在这种情况下,#if总是返回false,不管flag的值如何

我甚至试过:

const int flag2 = flag;
#define FLAG flag2

#if FLAG>0
    #define DEBUG
#endif
结果与上面的示例相同。 我的问题是:有没有办法根据变量的值定义宏?欢迎提出任何想法,但请记住,我希望保持这种结构。否则就意味着要修改数千行代码


谢谢大家。

你们不能在运行时控制预处理器。编译程序时,先运行预处理器,然后处理所有预处理器标记。编译器只编译生成的代码


如果要在运行时决定是否要调用调试函数,则必须使用正常的
If
语句。我的建议是尽可能将调试代码放在一起,以便使用单个if语句启用/禁用它。

您无法在运行时控制预处理器。编译程序时,先运行预处理器,然后处理所有预处理器标记。编译器只编译生成的代码


如果要在运行时决定是否要调用调试函数,则必须使用正常的
If
语句。我的建议是尽可能将调试代码放在一起,以便使用单个if语句启用/禁用它。

预处理在编译器看到代码之前完成,因此调试在编译时消失

也许您可以更改调试功能:

bool g_enableDebug = false;

void debug( const std::string& msg ) // note the const ref for efficiency
{
    if( g_enableDebug )
    {
      if ((flag && MASK_I_DEFINED_SOMEWHERE_FOR_STUFF) != 0)
      {
         std::cout << message << std::endl;
      }
    }
}

预处理是在编译器看到代码之前完成的,因此调试在编译时完成

也许您可以更改调试功能:

bool g_enableDebug = false;

void debug( const std::string& msg ) // note the const ref for efficiency
{
    if( g_enableDebug )
    {
      if ((flag && MASK_I_DEFINED_SOMEWHERE_FOR_STUFF) != 0)
      {
         std::cout << message << std::endl;
      }
    }
}

建立在@metal solution之上

我的建议是:

#define DEBUG(message) \
if(g_enableDebug) {    \
    debug(message);    \
}
其中debug()是@metal….定义的调试函数。。。。 你可以用它

DEBUG("This is a trace");

这样,当跟踪关闭时,就不会产生函数调用的成本。

基于@metal solution构建

我的建议是:

#define DEBUG(message) \
if(g_enableDebug) {    \
    debug(message);    \
}
其中debug()是@metal….定义的调试函数。。。。 你可以用它

DEBUG("This is a trace");

这样,当跟踪关闭时,您就不会产生函数调用的成本。

您只需要一个标志来确定是否将调试消息发送到某个地方(即stdout、file等)。此标志可以是全局布尔变量。然后,您可以定义一个宏调试(…),其中包含检查该标志的代码,如果该标志为true,则执行调试

现在的挑战是能够在运行时调整此标志。您可以有一个单独的逻辑来查找当前运行目录中是否存在文件(即debug.cfg)。如果存在,请将全局标志更改为true。否则,设置为false

使用这个简单的方法,要启用调试,只需在适当的目录中创建一个文件。要禁用调试,请删除该文件


一旦有了这些,就可以通过让debug.cfg包含信息来进一步增强调试功能。您可以做的一些事情是调试级别(即信息、错误、警告等)或仅为特定代码区域(即类名)启用调试。

您只需要一个标志来确定是否将调试消息发送到某个地方(即标准输出、文件等)。此标志可以是全局布尔变量。然后,您可以定义一个宏调试(…),其中包含检查该标志的代码,如果该标志为true,则执行调试

现在的挑战是能够在运行时调整此标志。您可以有一个单独的逻辑来查找当前运行目录中是否存在文件(即debug.cfg)。如果存在,请将全局标志更改为true。否则,设置为false

使用这个简单的方法,要启用调试,只需在适当的目录中创建一个文件。要禁用调试,请删除该文件

一旦有了这些,就可以通过让debug.cfg包含信息来进一步增强调试功能。您可以做的一些事情是调试级别(即信息、错误、警告等)或仅为特定代码区域(即类名)启用调试

我的问题是:有没有办法根据变量的值定义宏

不可以。您可以定义要替换为该变量的宏,但不能根据变量值定义宏或不定义宏。因为宏是在预编译期间计算的,所以所有宏都将在运行程序之前定义或不久(换句话说,在变量初始化并具有值之前很久)

欢迎提出任何想法,但请记住,我希望保持这种结构。否则就意味着要修改数千行代码

试试这个:

unsigned int flag = 0xFFFFFFFF;

void debug(const std::string& message) // const & for efficiency
{
#ifdef DEBUG
    if ((flag && MASK_I_DEFINED_SOMEWHERE_FOR_STUFF) != 0)
    {
        std::cout << message << std::endl;
    }
#endif
}
或者,您可以定义日志宏以避免同时调用函数:

#ifdef DEBUG
#    define DBGLOG(x) debug(x)
#else
#    define DBGLOG(x)
#endif
这样,当未定义DEBUG时,所有DBGLOG调用都将计算为一个空源代码行(没有比这更有效的了)

关于效率方面的一个注意事项:除非您有极端的效率要求,否则日志调用的性能可能并不重要。为了确定它们是否重要,首先设定一个目标(“我希望应用程序没有明显的延迟”,“我希望每秒处理150条消息”,等等),然后通过强调应用程序来衡量性能(即,运行测试部分1000次左右,测量经过的时间,然后除以1000),然后找出性能最差的违规者,并对其进行优化

性能优化
#ifdef DEBUG
#    define DBGLOG(x) debug(x)
#else
#    define DBGLOG(x)
#endif