请教一个 C 宏的写法 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
liuidetmks
V2EX    程序员

请教一个 C 宏的写法

  •  
  •   liuidetmks 2022-02-18 09:19:39 +08:00 2743 次点击
    这是一个创建于 1387 天前的主题,其中的信息可能已经有所发展或是发生改变。
    #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 编译时候,抛出错误 "其他特殊情况,需要处理"

    第 1 条附言    2022-02-18 11:12:31 +08:00
    感谢大家的回复,
    目前,有两种做法,一种直接抛出一个语法错误 define TODO(a) TODO##a
    第二是 _Static_assert 抛出英文错误(中文会展示\uxxxx ) 唯一的困扰是,其他人看到这个错误会莫名其妙

    这个问题太 tricky
    或者说有更好的解决方法吗.
    一个业务 分支太且深,一次只能专注于一个链路。想减轻下大脑负担, 有什么好的实践吗?
    15 条回复    2022-02-18 10:56:31 +08:00
    philon
        1
    philon  
       2022-02-18 09:31:54 +08:00
    宏定义里`#`会用于字符串转换和拼接,不能用宏来定义新的宏

    另外我不太理解你的需求,难道想把预处理和运行时的逻辑混在一起?怕是不现实
    zhyl
        2
    zhyl  
       2022-02-18 09:40:04 +08:00
    xyz1001
        3
    xyz1001  
       2022-02-18 09:46:41 +08:00   1
    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
        4
    nicebird  
       2022-02-18 09:46:53 +08:00
    不知道咋写,如果 c++直接 static_assert(false, msg)
    yolee599
        5
    yolee599  
       2022-02-18 09:52:36 +08:00
    1. “#” 用于连接两个字符串,不能这样用
    2. 宏是编译预处理,不是运行时,所以不可能在运行的时候执行 #error “some msg”
    liuidetmks
        6
    liuidetmks  
    OP
       2022-02-18 09:56:39 +08:00
    @zhyl 我先想的是这样,单这样只能笼统的报出一个语法错误,不能提示后面的消息. 看来也只能这样了

    @philon 需求就是,开发过程中,有很多流程,有时候只能专注于某一个流程,其他的流程只能打上 TODO 标签,
    在 debug 的时候可以正常调试,但是 release 时候会提示哪些分支没完成。
    takitooru
        7
    takitooru  
       2022-02-18 10:03:27 +08:00
    #ifdef DEBUG
    #define TODO(MSG)
    #else
    #error Invalid TODO_
    #endif
    ysc3839
        8
    ysc3839  
       2022-02-18 10:03:48 +08:00 via Android
    zhyl
        9
    zhyl  
       2022-02-18 10:05:53 +08:00   1
    或者用这种方式:
    ```
    #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
        10
    Kasumi20  
       2022-02-18 10:19:22 +08:00
    除非可以转义#号,不然只能一行变三行:
    #ifndef NDEBUG
    #error "TODO MSG"
    #endif
    lonewolfakela
        11
    lonewolfakela  
       2022-02-18 10:43:14 +08:00   1
    @xyz1001 C 语言( c11 )的话,应该可以
    #if defined(DEBUG)
    #define TODO(MSG)
    #else
    /// 抛出 MSG 编译错误
    #define TODO(MSG) _Static_assert(false, MSG)
    #endif
    lesismal
        12
    lesismal  
       2022-02-18 10:45:21 +08:00
    #if defined(DEBUG)
    #define TODO(MSG)
    #else
    #define TODO error // 没必要还非得是宏函数吧
    #end
    liuidetmks
        13
    liuidetmks  
    OP
       2022-02-18 10:47:31 +08:00
    @lonewolfakela 这个我试了,只能英文 .. 中文是 \uxxxx, 不过目的也达到了,到错误处看代码就行了,只是别人编译的话看到错误可能莫名其妙 感谢回复
    exiledkingcc
        14
    exiledkingcc  
       2022-02-18 10:48:49 +08:00
    最简单的方案就是上面提到的 _Static_assert
    jackmod
        15
    jackmod  
       2022-02-18 10:56:31 +08:00
    不求严谨的话直接写一个超长的字符串也行
    展开之后就是按变量名对待的,其结果就是未定义变量
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2655 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 05:56 PVG 13:56 LAX 21:56 JFK 00:56
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86