我刚刚在C中遇到了一个我非常喜欢的DEBUG宏
#ifdef DEBUG_BUILD
# define DEBUG(x) fprintf(stderr, x)
#else
# define DEBUG(x) do {} while (0)
#endif
Run Code Online (Sandbox Code Playgroud)
我猜一个C++模拟会是: -
#ifdef DEBUG_BUILD
# define DEBUG(x) cerr << x
#else
# define DEBUG(x) do {} while (0)
#endif
Run Code Online (Sandbox Code Playgroud)
编辑:通过"调试宏"我的意思是"在调试模式下运行程序时可能派上用场的宏".
我想用一个相同的参数来创建一个调试日志功能printf.但是在优化构建期间可以由预处理器删除的一个.
例如:
Debug_Print("Warning: value %d > 3!\n", value);
Run Code Online (Sandbox Code Playgroud)
我查看了可变参数宏,但并非所有平台都可以使用.gcc支持他们,msvc不支持他们.
我正在尝试做一个调试系统,但它似乎不起作用.
我想要完成的是这样的事情:
#ifndef DEBUG
#define printd //
#else
#define printd printf
#endif
Run Code Online (Sandbox Code Playgroud)
有没有办法做到这一点?我有很多调试消息,我不想这样做:
if (DEBUG)
printf(...)
code
if (DEBUG)
printf(...)
...
Run Code Online (Sandbox Code Playgroud) 在C中,定义类似printf的宏的正确方法是什么,只有在定义了DEBUG符号时才会打印?
#ifdef DEBUG
#define DEBUG_PRINT(???) ???
#else
#define DEBUG_PRINT(???) ???
#endif
Run Code Online (Sandbox Code Playgroud)
哪里??? 是我不知道该填写什么的地方
我一直在使用这样的东西:
int main(int argc, char *argv[])
{
#ifdef DEBUG
printf("RUNNING DEBUG BUILD");
#else
printf("Running... this is a release build.");
#endif
...
Run Code Online (Sandbox Code Playgroud)
但是,这需要我使用-DDEBUG进行编译以进行调试构建.GCC是否为我提供了一些方法来确定何时使用调试符号(-g标志)进行编译,例如定义我自己可以检查的预处理器宏?
什么MACRO可以用来关闭printf语句,而不是全部删除它们用于部署版本,我只想关闭它们,跳过它们,忽略它们.
编辑:我个人使用gcc,但代码是一个更大的项目的一部分,将在运行Ubuntu的熊猫板上编译.
我有一些调试代码如下所示:
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)
void __my_error(const char*loc, const char *fmt, ...);
#define my_error(fmt, ...) __my_error(AT, fmt, ##__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)
使用最后一个宏,因此我可以将位置插入到调试输出中,以确定错误发生的位置.但是,当我调用这样的函数时:
my_error("Uh oh!");
Run Code Online (Sandbox Code Playgroud)
我喜欢我的代码是C99,所以我觉得这个时候编译,我得到以下错误:
error: ISO C99 requires rest arguments to be used
Run Code Online (Sandbox Code Playgroud)
我知道我可以通过改变呼叫来解决这个问题
my_error("Uh oh!", NULL);
Run Code Online (Sandbox Code Playgroud)
但有什么方法可以让这个看起来不那么难看?谢谢!
我一直在尝试在C中实现一个函数宏,它将"DEBUG:"添加到参数中,并将其参数传递给printf:
#define DBG(format, ...) printf("DEBUG: " #format "\n", __VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)
这给了我gcc中的这个错误:
src/include/debug.h:4:70: error: expected expression before ‘)’ token
#define DBG(format, ...) printf("DEBUG: " #format "\n", __VA_ARGS__)
^
Run Code Online (Sandbox Code Playgroud)
据说,它应该串行化格式,并将其变量参数传递给printf,但到目前为止,我无法通过此错误.
编辑
在放弃了字符串化参数和double-hashing(##)后,__VA_ARGS__我现在有了这个错误:
src/lib/cmdlineutils.c: In function ‘version’:
src/lib/cmdlineutils.c:56:17: warning: ISO C99 requires rest arguments to be used [enabled by default]
DBG("version()");
Run Code Online (Sandbox Code Playgroud)
我应该在争论后放置逗号吗?
DBG("version()",); // ?
Run Code Online (Sandbox Code Playgroud)
作为参考,DBG()现在看起来像这样:
#define DBG(format, ...) printf("DEBUG: " format "\n", ##__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud) 我有一个多文件C程序.我希望用户能够在运行时指定不同的调试级别.
实现这个的最佳方法是什么?
我正在考虑将调试(级别,"消息")类型函数导出并在任何地方使用.还有更好的/其他想法吗?
对于调试日志记录,我经常看到并使用类似的东西
#ifdef DEBUG
#define DLOG(fmt, args...) printf("%s:%d "fmt,__FILE__,__LINE__,args)
#else
#define DLOG(fmt, args...)
#endif
Run Code Online (Sandbox Code Playgroud)
但在很多地方,我看到第二个#define被替换了
#define DLOG(fmt, args...) do {} while (0)
Run Code Online (Sandbox Code Playgroud)
特别是,有这个答案,对同一问题的另一个答案的评论表明,问题将出现在像
if (condition)
DLOG("foo");
Run Code Online (Sandbox Code Playgroud)
虽然我的快速测试表明,行中产生的分号本身将作为条件内的无操作语句.
是一个或其他的什么和do {} while (0)好?如果是这样,为什么?还有其他更好的东西吗?