微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

是否有一种标准方法可以保证在编译翻译时评估某个常量表达式? 6.6 常量表达式 ...

如何解决是否有一种标准方法可以保证在编译翻译时评估某个常量表达式? 6.6 常量表达式 ...

我很惊讶 C 不保证在编译(翻译)时计算某些(常量)表达式。

C11(6.6 常量表达式)(强调):

一个常量表达式可以在翻译过程中而不是运行时进行计算,...

因此,有两个问题:

  1. 是否有一种标准方法可以保证在编译(翻译)时对某个(常量)表达式求值?
  2. 额外的问题:为什么C不保证呢?保证它的(技术)障碍是什么?

解决方法

C 标准通常无法分别描述在编译时和运行时可能发生的情况。整个语言基于 C17 5.1.2.3 中“抽象机器”的(相当无用的)概念

本国际标准中的语义描述描述了一个 与优化问题无关的抽象机器。
...
一个表达式的求值一般包括两个值 副作用的计算和启动...
在抽象机中,所有表达式都按照语义指定的方式进行评估。一个 实际实现不需要计算表达式的一部分,如果它可以推断出它的 不使用价值,也不会产生任何需要的副作用...

上面包含了evaluation的正式定义,这也没什么帮助。基本上,只要尊重副作用和“可观察的行为”,实现就可以自由地以优化的方式做任何事情。没有规定编译器必须执行某些优化。构建一个完全没有优化的编译器是可能的,它仍然可以是一个符合要求的实现。

至于 6.6 和常量表达式,目的肯定是说明什么是有效的编译时常量的规则。如果在编译时不计算整数常量表达式,那么生成可执行文件就变得非常不切实际,以至于整个语言都会崩溃。间接地,除非在编译时评估常量表达式,否则有许多要求无法满足。

例如,如果在编译时不知道静态存储持续时间对象的数组大小,那么您将如何生成用于初始化它们的启动代码?它必须在调用 main() 之前发生 - 这实际上是由 5.1.2 保证的:

所有具有静态存储期的对象都应在程序启动前进行初始化(设置为其初始值)。

如果 main 包含 static int arr [5] = {1,2,3,4,5};,那么当我们到达声明时,这个对象必须已经被初始化。因此,如果我的示例中的整数常量 5(整数常量表达式)实际上是在编译时计算的,我们只能满足 5.1.2。

,

可能只是英语的轻度歧义用法:术语“can”在这里(恕我直言)用于表达表达式是编译时可评估的逻辑可能性,而不是一个可选,实现指令。

如果我们从标准中引用您引用的段落的全文(粗斜体是我的),那么我相信,可以保证评估有效 发生在编译时:

6.6 常量表达式
...

说明
2 可以在翻译期间而不是运行时评估常量表达式,因此 可以用在常量可能存在的任何地方

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。