请教一个 C 宏的写法

2022-02-18 09:19:39 +08:00
 liuidetmks
#if defined(DEBUG)
#define TODO(MSG)
#else
/// 抛出 MSG 编译错误
#define TODO(MSG) #error MSG  // 这样不行. #好像不能在后面
#end

在 DEBUG 模式, 忽略 TODO(MSG)
Rlease 模式, 抛出编译错误 类似于 #error MSG

不知道有没有类似于 defined()预处理方法直接抛出错误

if(xxx){
/// 主流程
}else{
TODO('其他特殊情况,需要处理')
}

这样在 release 编译时候,抛出错误 "其他特殊情况,需要处理"

1983 次点击
所在节点    程序员
15 条回复
philon
2022-02-18 09:31:54 +08:00
宏定义里`#`会用于字符串转换和拼接,不能用宏来定义新的宏

另外我不太理解你的需求,难道想把预处理和运行时的逻辑混在一起?怕是不现实
zhyl
2022-02-18 09:40:04 +08:00
xyz1001
2022-02-18 09:46:41 +08:00
C++11 的话可以这么写:

```
#if defined(DEBUG)
#define TODO(MSG)
#else
/// 抛出 MSG 编译错误
#define TODO(MSG) static_assert(false) // 这样不行. #好像不能在后面
#endif

int main() {
TODO("test");
return 0;
}
```

C 的话不是很熟悉有没有对应的写法
nicebird
2022-02-18 09:46:53 +08:00
不知道咋写,如果 c++直接 static_assert(false, msg)
yolee599
2022-02-18 09:52:36 +08:00
1. “#” 用于连接两个字符串,不能这样用
2. 宏是编译预处理,不是运行时,所以不可能在运行的时候执行 #error “some msg”
liuidetmks
2022-02-18 09:56:39 +08:00
@zhyl 我先想的是这样,单这样只能笼统的报出一个语法错误,不能提示后面的消息. 看来也只能这样了

@philon 需求就是,开发过程中,有很多流程,有时候只能专注于某一个流程,其他的流程只能打上 TODO 标签,
在 debug 的时候可以正常调试,但是 release 时候会提示哪些分支没完成。
takitooru
2022-02-18 10:03:27 +08:00
#ifdef DEBUG
#define TODO(MSG)
#else
#error Invalid TODO_
#endif
ysc3839
2022-02-18 10:03:48 +08:00
zhyl
2022-02-18 10:05:53 +08:00
或者用这种方式:
```
#define DO_PRAGMA_(x) _Pragma(#x)
#define DO_PRAGMA(x) DO_PRAGMA_(x)
#define TODO(msg) DO_PRAGMA(GCC error msg)

int main() {
TODO("compile error");
TODO("编译错误");
return 0;
}
```

已知的问题:clang 下 msg 如果是中文不会显示错误内容
Kasumi20
2022-02-18 10:19:22 +08:00
除非可以转义#号,不然只能一行变三行:
#ifndef NDEBUG
#error "TODO MSG"
#endif
lonewolfakela
2022-02-18 10:43:14 +08:00
@xyz1001 C 语言( c11 )的话,应该可以
#if defined(DEBUG)
#define TODO(MSG)
#else
/// 抛出 MSG 编译错误
#define TODO(MSG) _Static_assert(false, MSG)
#endif
lesismal
2022-02-18 10:45:21 +08:00
#if defined(DEBUG)
#define TODO(MSG)
#else
#define TODO error // 没必要还非得是宏函数吧
#end
liuidetmks
2022-02-18 10:47:31 +08:00
@lonewolfakela 这个我试了,只能英文 .. 中文是 \uxxxx, 不过目的也达到了,到错误处看代码就行了,只是别人编译的话看到错误可能莫名其妙 感谢回复
exiledkingcc
2022-02-18 10:48:49 +08:00
最简单的方案就是上面提到的 _Static_assert
jackmod
2022-02-18 10:56:31 +08:00
不求严谨的话直接写一个超长的字符串也行
展开之后就是按变量名对待的,其结果就是未定义变量

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/834690

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX