【问题标题】:What is the definition of "arithmetic operation" in C99?C99中“算术运算”的定义是什么?
【发布时间】:2014-08-31 04:42:46
【问题描述】:

在 C99 中,术语 算术运算 出现了 16 次,但我没有看到它的定义。

算术运算符这个词在文本中只出现了两次(同样没有定义),但它确实出现在索引中:

算术运算符

添加剂,6.5.6,G.5.2
按位,6.5.10、6.5.11、6.5.12
递增和递减, 6.5.2.4, 6.5.3.1
乘法 6.5.5, G.5.1
班次,6.5.7
一元,6.5.3.3

然后我们有- | 987654324 &(二进制)-- 987654326 @ *(二进制)% 987654330 >> 987654331 @ ~ AS算术运算符,如果索引被认为是规范的!

也许我们应该将算术运算识别为算术运算符的使用。但 F9.4.5 表示 sqrt() 函数也是算术运算,详情请参阅 IEC 60559(又名 IEEE754)。所以一定要有算术运算,而不仅仅是使用算术运算符。

【问题讨论】:

  • 大概<math.h> 中的所有内容也是“算术”?
  • 准确的说是sqrt is fully specified as a basic arithmetic operation in IEC 60559.
  • @chux 那么,你会排除按位运算符吗?
  • @Matt 是的,按位运算符比算术更好地描述为逻辑运算符。当然,这是在意见范围内。
  • @ChronoKitsune 有些东西是根据算术运算指定的。 6.2.6.2#1 脚注“没有对有效值的算术运算可以生成陷阱表示”促使我提出这个问题;但是至少 7.14#3、F.8.1 和 H.3 也指定了仅适用于算术运算的行为。

标签: c c99 language-lawyer


【解决方案1】:

由于我们没有正式的定义,让我们看看我们是否可以拼凑出对算术运算应该是什么的基本解释。这将是推测性的,但我找不到任何明显的缺陷报告或涵盖此问题的未解决问题。

我想我会从算术类型开始,这在 6.2.5 部分 Types18 段中有介绍(强调我的未来/em>):

整数和浮点类型统称为算术类型。 每个算术类型属于一个类型域:实类型域 包含实类型,复类型域包含 复杂类型。

好的,所以我们知道算术运算必须对整数或浮点类型进行运算。那么什么是操作?似乎我们可以很好地从 5.1.2.3 Program execution 段落 2 部分定义它:

访问易失性对象、修改对象、修改文件或 调用执行任何这些操作的函数都是侧面的 效果,11) 是执行状态的变化 环境。 [...]

所以修改一个对象或调用一个函数来做这件事,这是一个操作。什么是对象3.14 部分说:

执行环境中的数据存储区域,内容为 可以表示值

虽然标准似乎更宽松地使用术语操作来表示评估,例如在7.12.1 错误条件的处理部分中它说:

每个函数的行为都是为所有指定的 其输入参数的可表示值,除非另有说明 否则。 每个函数都应该像单个函数一样执行 操作 不会产生任何外部可见的异常 条件。

6.5 Expressions8 中说:

一个浮动表达式可以被压缩,也就是说,被评估为 这是一个原子操作 [...]

所以这似乎意味着评估是一种操作。

因此,从这些部分看来,几乎所有算术运算符和任何数学函数都属于算术运算的常识定义。

【讨论】:

  • 算术运算符中,只有复合赋值运算符才能真正修改对象,所以这个定义是错误的。
  • @BenVoigt 很好地说明了存储区域,如果它产生一个值,则必须修改存储区域。
  • C 中的运算符不会“返回”值。它们出现在被评估的表达式中。只有在具有用户定义的运算符重载函数的 C++ 中,运算符和返回的概念才会混淆。
  • @BenVoigt 我将措辞改为生产。
  • 嗯,我明白你的意思了。显然,有许多不同的方法可以解释算术运算可能是什么,也可能不是。
【解决方案2】:

我能找到的最有说服力的隐含定义在于 7.14 信号处理,第 3 段,在 SIGFPE 信号的定义中:

SIGFPE - 错误的算术运算,例如零除或导致溢出的运算

然后可能会得出结论,任何可能导致 SIGFPE 引发的操作都可以被视为算术运算;只有算术运算才能引发 SIGFPE 信号。

这几乎涵盖了<math.h> 和算术运算符以及<complex.h> 中的所有内容(如果已实现)。虽然对于整数类型可能不会发出信号,但允许有符号溢出和其他“异常”条件生成陷阱表示,这意味着在获得有效值之前不能可靠地执行其他操作 - 只能通过以下方式完成任务。换句话说,该定义同样适用于对整数值的操作。

因此,除了获取对象/类型的大小、取消引用指针和获取对象地址之外,几乎所有操作都可能被视为算术运算。请注意a[n]*((a) + (n)),所以即使使用数组也可以视为算术运算。

【讨论】:

    【解决方案3】:

    算术运算涉及数字操作sqrt 也操纵数字,这可能是标准说它是算术运算的原因。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-31
      • 1970-01-01
      • 2021-03-30
      • 1970-01-01
      • 2021-02-06
      • 1970-01-01
      相关资源
      最近更新 更多