VS 2015跟CLOCK_PER_SEC在预处理器中的代码不兼容。

3

我正在将我的旧代码库移植到VS 2015。

这段代码是:

#if XYZ 
  ....
#elif CLOCKS_PER_SEC > 999 //<< Getting error here.
  ...
#endif

我在CLOCKS_PER_SEC这一行遇到了错误:

Severity    Code    Description 
Error       C1012   unmatched parenthesis: missing ')'

查看在time.h头文件中CLOCKS_PER_SEC的定义

// The number of clock ticks per second
#define CLOCKS_PER_SEC  ((clock_t)1000)

看起来是因为预处理器宏无法与 clock_t 一起使用。

请建议我如何修复?


c:\Program Files (x86)\Windows Kits\10\Include\10.0.10150.0\ucrt\time.htime.h 文件的名称。 - Ashish Negi
@specializt:CLOCKS_PER_SEC以其他方式定义并不奇怪。没有人承诺它将永远定义为(1000)。事实上,(1000)是无效的定义。语言规范要求它具有clock_t类型,而不是int类型。 - AnT stands with Russia
@AnT 这可能是一些奇怪的UNIX规范,但它绝对不是MSVC规范 - UNIX或可能甚至是POSIX规范与此问题无关。 - specializt
1
@specializt:错了。MSVC 2015 完全实现了 C99 语言标准。与其他编译器一样,它也有一些与标准不同的地方(错误),但这些只是次要的局部问题(而且任何编译器都存在)。但是,在这个问题的背景下,这是不相关的,因为观察到的行为是完全标准的。事实上,CLOCKS_PER_SEC 的问题与 C99 标准中的缺陷有关,而不是 MSVC 编译器中的某些问题。原始的 C99 标准在定义 CLOCKS_PER_SEC 时存在缺陷。这个缺陷在后来的一个 TC 中得到了修复。 - AnT stands with Russia
1
这是官方缺陷报告的链接:http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_281.htm - AnT stands with Russia
显示剩余5条评论
1个回答

4

C语言规范在7.1.4/1中说明:

所有列举为整数常量表达式的类对象宏,在 #if 预处理指令中也必须适用。

然而,宏 CLOCKS_PER_SEC 并未被列举为整数常量表达式 (7.27.1/2)。这意味着它不能在 #if 中使用。

这正是你刚刚遇到的问题。你应该开发一种替代方法来实现代码中的条件编译。在一般情况下,CLOCKS_PER_SEC 不能与 #if 一起使用。语言规范要求 CLOCKS_PER_SEC 具有 clock_t 类型,而不是 int 类型,这意味着在那里进行强制转换是完全合理的。

P.S. 请注意,您当前的定义 CLOCKS_PER_SEC 符合整数常量表达式的条件,但 #if 对条件表达式施加了一些额外的要求。即,不允许进行强制转换。

P.P.S. 在 C99 的原始版本中,CLOCKS_PER_SEC 被描述为一个常量表达式。然而,在 C99+TC2 中,单词“常量”不再存在。这是为了消除上述要求之间的矛盾:1) 可在 #if 下使用常量表达式宏,这排除了强制转换,2) CLOCKS_PER_SEC 具有 clock_t 类型,只能通过强制转换实现。相应的缺陷报告可以在此处找到:http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_281.htm


“通过扩展为整数常量表达式,您的意思是任何宏的最终扩展都将是像1000这样的整数值吗?” - Ashish Negi
有没有关于“其他方式”的建议?有没有比覆盖全局 CLOCKS_PER_SEC 更好的方法?在那个位置,是否可以添加模板来在编译时发现如果我覆盖的值1000偏离 time.h 的未来更改而产生错误? - Ashish Negi
否则,我可以更改预处理器状态以进行编译时检查...即将#elif更改为if条件。 - Ashish Negi
并不是说强制类型转换不允许(虽然它们确实不允许),而是扩展后的语法不允许使用强制类型转换。((clock_t)1000)被预处理成了((0)1000),因为预处理器对typedef一无所知。 ((0)1000)是语法错误。 - user743382

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接