【发布时间】:2012-12-14 08:27:39
【问题描述】:
gcc/g++ 4.7.2
CXXFLAGS -Wall -Wextra -g -O2
你好,
我有这个使用 C 风格编写的头文件 (mu_test.h)。它包含以下marcos
#define GET_ERROR() ((errno == 0) ? "None" : strerror(errno))
#define LOG_ERR(fmt, ...) fprintf(stderr, "[ERROR] %s:%d: errno: %s " fmt "\n", __func__, __LINE__, GET_ERROR(), ##__VA_ARGS__)
#define MU_ASSERT(test, msg) do { \
if(!(test)) { \
LOG_ERR(msg); \
return msg; \
} \
} while(0)
我有一个使用 g++ 编译的 cpp 文件 (floor_plan_src.cpp),其中包含 mu_test.h
#include "mu_test.h"
char* test_memory_allocation()
{
plan = new floor_plan();
MU_ASSERT(plan != NULL, "Failed to allocate memory for floor_plan");
return NULL;
}
我收到此警告:
deprecated conversion from string constant to ‘char*’
所以我传递给类似函数的 marco 的字符串常量不喜欢它(C 字符串),因为我使用 g++ 编译了我的源代码。
我认为这个问题与混合 c/c++ 有关。
解决方案 1:将 mu_test.h 中的所有宏用 extern "C" 包装
#ifdef __cplusplus
extern "C"
{
#endif /* _cplusplus */
#define GET_ERROR() ((errno == 0) ? "None" : strerror(errno))
#define LOG_ERR(fmt, ...) fprintf(stderr, "[ERROR] %s:%d: errno: %s " fmt "\n", __func__, __LINE__, GET_ERROR(), ##__VA_ARGS__)
#define MU_ASSERT(test, msg) do { \
if(!(test)) { \
LOG_ERR(msg); \
return msg; \
} \
} while(0)
#ifdef __cplusplus
}
#endif /* __cplusplus */
解决方案 1 仍然给了我同样的警告。
解决方案2:将头文件包装在 floor_plan_src.cpp 中
extern "C" {
#include "mu_test.h"
}
解决方案 2 仍然给了我同样的警告
解决方案 3:包装函数
extern "C" char* test_memory_allocation()
{
plan = new floor_plan();
MU_ASSERT(plan != NULL, "Failed to allocate memory for floor_plan");
return NULL;
}
方案3同上
解决方案 4: 尝试将常量字符串转换为非 const char*
MU_ASSERT(plan != NULL, (char*)"Failed to allocate memory for floor_plan");
出现以下错误:
expected primary-expression before char
"[ERROR] %s:%d: errno: %s " cannot be used as a function
非常感谢您的任何建议,
【问题讨论】:
-
你需要
##中的##__VA_ARGS__ -
这是避免尾随逗号所必需的,即没有它就无法工作。 LOG_ERR("错误发生");因为我没有传递任何论据。
-
您在
MU_ASSERT中使用LOG_ERR有点危险,如果msg意外包含格式说明符,它会崩溃并烧毁。你可能应该这样称呼它:LOG_ERR("%s", msg);.