Transferring commentary into an answer and expanding on the discussion.
C++14是第一个包含数字标点符号的标准,使用'
来分隔数字组.C++不能使用_
而不是'
是有技术原因的.C++14还添加了前缀为0b
或0B
的二进制常量.
C23将增加数字标点符号和二进制常量功能.这使它与C++保持一致,但数字标点符号使得C代码的临时解析比以前困难得多.
这意味着你可以用GCC的一个版本来编译代码,这个版本可以识别-std=c2x
(或者-std=c23
或者-std=c24
--我不确定他们会 Select 哪一个).
不能用只识别C18(或者是C17?)或更早的标准的C编译器编译代码.这是因为输入是由C预处理器标记的.
C11标准§6.10.1 Conditional inclusion ¶6规定:
每个指令的条件都按顺序判断.如果它的计算结果为false(零),则跳过它所控制的组:指令只通过确定指令的名称进行处理,以跟踪嵌套条件的级别;其余指令的预处理标记被忽略,组中的其他预处理标记也被忽略.仅处理控制条件计算结果为true(非零)的第一个组.如果没有一个条件计算为true,并且有一个#else
指令,则处理由#else
控制的组;如果没有#else
指令,则跳过#endif
之前的所有组.
问题是,它是在"预处理令牌"上工作的,在C23之前,0B0000'0001
中的'
开始一个字符常量令牌,但没有匹配的右引号,所以令牌无效/不完整.
有一些可能的、但令人讨厌的、老套的解决办法.其中一个是comment分中Jarod42分建议的:
添加// workaround: final quote for pre-c2x: '
可能是一种变通办法.
同样,您可以确保所有带标点符号的数字都包含偶数个单引号.例如,以八进制数字分组对二进制进行标点也可以:0B00'000'001
.始终使用偶数个标点符号字符!
Arteyr suggested:
您还可以将C++程序放在不同的文件中,并拥有
#ifdef __cplusplus
#include "./cpp_header.hpp"
#endif
所以C预处理器甚至不会打开包含0B0000'0001
个字符的文件.
请注意,用二进制表示64位数字是不明智的,即使使用标点符号也是如此.如果你用八位字节来标点,那么也会有7个标点符号!
0B10100000'00000100'00000000'00000010'00000000'00101010'00000000'00111000
这在十六进制中会更明智,但在四个四位十六进制数字之间会有三个分隔符,这仍然会给C18或更早版本以及C++11或更早版本的编译器带来麻烦:
0xA004'0002'002A'0038
我的建议是:
- 在您需要使用的所有C和C++编译器都支持数字标点符号之前,不要使用它.
- 不要使用二进制来表示64位值.改用十六进制.
(我顺便指出,C++原始字符串字面量对于专门的代码解析器来说更是一场噩梦. 幸运的是,原始字符串字面量不是C23的一部分.