将Zed Shaw的调试宏移植到MSVC

时间:2016-09-22 15:21:53

标签: c multithreading debugging macros strerror

我在他的网站上找到了Zed Shaw的调试宏,当时他的C书和#34;学习艰难的方式"可以自由阅读。它最初是为Linux设计的,它运行得很好,已经使用了一段时间。

现在,我开始为Windows编写C代码,并且我已经使用Visual Studio了。我想在我正在处理的项目中使用这些调试宏。

问题如下: 让我们说我想使用check宏来确保函数返回时没有错误。

display = al_create_display(640, 480);
check(display, "Failed to create display");

将使用的宏的定义如下:

#define clean_errno() (errno == 0 ? "None" : strerror(errno))
#define log_err(M, ...) fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__)
#define check(A, M, ...) if(!(A)) { log_err(M, ##__VA_ARGS__); errno=0; goto error; }

但是,我遇到的问题是Visual Studio将strerror()标记为已弃用并中止编译。我计划在项目中使用线程,所以我不想去"忽略"路线,如果可能的话。

我做的是创建了一个clean_errno()函数,该函数与宏执行相同的操作,但使用全局缓冲区变量并调用strerror_s()复制到其中,然后返回指向{的指针{1}}宏。 但是现在我必须:

  • 要么为这一个3-line功能创建一个全新的标题和C文件,我认为这只是丰富的
  • 或者我只是在调试宏的标题中声明并实现该函数,它根本不被认为是好的C语言,也非常难看。

还有其他任何我不知道的技巧/黑客会为此提供一个优雅而简单的解决方案吗?

1 个答案:

答案 0 :(得分:0)

Strerror已弃用,因为它不是线程安全的。如果您不关心这个事实,那么您可以在VS中找到一些选项来关闭此警告。

但使用sterror_s()实现线程安全版本同样简单。请记住,您的宏可以做的不仅仅是计算表达式,特别是它完全可以在宏中分配缓冲区:

#define check(A, M, ...) \
    if(!(A)) { \
        char _buffer[128]; \
        strerror_s(_buffer, 128, errno); \
        fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " (M) "\n", __FILE__, \
                __LINE__, errno? _buffer : "None", ##__VA_ARGS__); \
        errno = 0; \
        goto error; \
    }

我没有测试过这段代码,所以它可能有一些错误,但它应该是一个开始。

相关问题