清理调试输出功能?

发布于 2024-10-12 22:41:23 字数 1178 浏览 2 评论 0原文

我想编写一个函数,它将在我的程序中打印出错误消息/警告以及文件和文件。行号。 C中有这两个宏:

__FILE__
__LINE__

但是我认为有一个问题...当我编写这样的函数时:

#include <stdio.h>
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)
void error(const char *location, const char *msg)
{
#ifdef DEBUG
  printf("Error at %s: %s\n", location, msg);
#endif
}
int main(int , char**)
{
  error(AT, "fake error");
  return 0;
}

仍然有很多无用的函数调用&二进制文件中的垃圾(每次调用时 __FILE____LINE__ 的值),即使我为发布版本取消定义 DEBUG 也是如此。 那么我怎样才能更优雅地完成这个任务呢?我想要这样的东西:

#include <stdio.h>
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)
void error(const char *location, const char *msg)
{
  printf("Error at %s: %s\n", location, msg);
}
int main(int , char**)
{
#ifdef DEBUG
  error(AT, "fake error");
#endif
  return 0;
}

但不要在每次函数调用之前和之后编写 #ifdef DEBUG#endif - 这对于这样的任务来说太大了。并删除每个 error(AT, "fake error"); 手动调用也不是很优雅......

有什么想法吗?也许内联该函数(不会有帮助,不是吗)?一些宏或这个结构的改变?

I want to write an function that will print out error messages/warnings in my program together with the file & line number. There are these two macros in C:

__FILE__
__LINE__

but there's a problem in my opinion... When I'm writing a function like this:

#include <stdio.h>
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)
void error(const char *location, const char *msg)
{
#ifdef DEBUG
  printf("Error at %s: %s\n", location, msg);
#endif
}
int main(int , char**)
{
  error(AT, "fake error");
  return 0;
}

There are still a lot of useless function calls & trash (the values of __FILE__ and __LINE__ at every call) in the binary file, even if I undefine DEBUG for the release build.
So how can I accomplish this more elegant? I want something like this:

#include <stdio.h>
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)
void error(const char *location, const char *msg)
{
  printf("Error at %s: %s\n", location, msg);
}
int main(int , char**)
{
#ifdef DEBUG
  error(AT, "fake error");
#endif
  return 0;
}

But not writing #ifdef DEBUG and #endif before and after every function call - that would be too huge for such an task. And remove every error(AT, "fake error"); call manually isn't really elegant as well...

Any ideas? Maybe inline the function (would not help, wouldn't it)? Some macro or an change of this construct?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

念三年u 2024-10-19 22:41:23

只需将 error 变成一个宏:

#ifdef DEBUG
# define ERROR(l, m) error(l, m)
#else
# define ERROR(l, m)
#endif

然后在你的函数中编写

ERROR(AT, "fake error");

当然,你也可以简化 ERROR 并去掉 AT 作为第一个参数,直接指定这些信息在宏定义中。

Just turn error into a macro:

#ifdef DEBUG
# define ERROR(l, m) error(l, m)
#else
# define ERROR(l, m)
#endif

then, in your functions, write

ERROR(AT, "fake error");

Of course, you could also simplify ERROR and get rid of AT as the first parameter, directly specifying this information in the macro definition.

惜醉颜 2024-10-19 22:41:23

error() 包装在宏中确实是正确的方法 - 我会这样写:

#ifdef DEBUG
static void error(const char *file, long line, const char *msg)
{
  fprintf(stderr, "Error (%s:%ld): %s\n", file, line, msg);
}
#define error(msg) (error)(__FILE__, __LINE__, msg)
#else
#define error(msg) ((void)0)
#endif

Wrapping error() in a macro is indeed the right way to go - I'd write it like so:

#ifdef DEBUG
static void error(const char *file, long line, const char *msg)
{
  fprintf(stderr, "Error (%s:%ld): %s\n", file, line, msg);
}
#define error(msg) (error)(__FILE__, __LINE__, msg)
#else
#define error(msg) ((void)0)
#endif
靑春怀旧 2024-10-19 22:41:23

您可以使用此可变参数宏来模拟 printf ,它会使用所需的输出写入文件和行号。

#define eprintf(...) do {fprintf(stderr, "%s:%d: ", __FILE__, __LINE__);\
 fprintf(stderr, __VA_ARGS__);} while(0)

编辑:根据 jcsalomon 的建议修改了 eprintf

you can use this variadic macro to mimic printf which writes file and line no with desired out put.

#define eprintf(...) do {fprintf(stderr, "%s:%d: ", __FILE__, __LINE__);\
 fprintf(stderr, __VA_ARGS__);} while(0)

edit : modified eprintf from the suggestions of jcsalomon

阳光①夏 2024-10-19 22:41:23
#ifdef DEBUG
#define ERROR(msg) error(AT, msg)
#else
#define ERROR(msg)
#endif

int main( int argc, char * argv[] )
{
   ERROR( "fake error");
   return 0;
}
#ifdef DEBUG
#define ERROR(msg) error(AT, msg)
#else
#define ERROR(msg)
#endif

int main( int argc, char * argv[] )
{
   ERROR( "fake error");
   return 0;
}
羁绊已千年 2024-10-19 22:41:23

将错误替换为#define,

例如:

#ifdef DEBUG
#define error(a,b) printf("Error at %s: %s\n", (a), (b))
#else
#define error(a,b) 
#endif

您还可以将 AT 移至错误中,而不是每次都传递它

replace error with #define

something like:

#ifdef DEBUG
#define error(a,b) printf("Error at %s: %s\n", (a), (b))
#else
#define error(a,b) 
#endif

You could also move AT into error instead of passing it each time

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文