【问题标题】:Returning a variable while using a post increment in C在 C 中使用后增量时返回一个变量
【发布时间】:2013-03-15 02:26:02
【问题描述】:

我有一个名为var 的全局变量和一个函数foo。 (我知道这是一种不好的做法,但有时这是不可避免的)我想知道 C 标准(我正在使用 c99 编译)是否说明如果我尝试执行 var 会发生什么:

long foo(){
    return var++;
}

谢谢。

【问题讨论】:

  • 返回它的旧值,并存储增加的值。
  • 是的。它似乎按预期工作。我只是不确定按照标准来判断是否正确。
  • 没关系 - 和全局变量一样好。
  • 我添加了“language-lawyer”标签以防止这个问题因为“过于本地化”而被关闭。

标签: c global-variables standards c99 language-lawyer


【解决方案1】:

简答:

它将返回var 的副本,然后立即递增全局var。

长答案:

C11 6.5.2.4

"后缀++运算符的结果就是操作数的值。如 一个副作用,操作数对象的值增加了.."。/--/ 结果的值计算在副作用之前排序 更新操作数的存储值。

标准 5.1.2.3“程序执行”规定所有副作用必须在程序遇到序列点之前进行评估。 (大量关于序列点可以找到here)。

return 语句后有一个序列点 (C11 6.8/4)。

这意味着表达式 var++ 保证在 main() 中的任何代码继续之前被完全计算。

您的机器代码将如下所示:

  • 将var 的本地副本存储在堆栈上(或寄存器等)
  • 将全局 var 增加 1。
  • 从子程序返回。
  • 使用“copy-of-var”。

如果您改为使用前缀增量,则增量操作会在副本存储之前进行排序。

【讨论】:

  • 也许值得一提的是,上面的“机器代码”说明了为什么全局变量上的 ++ 不是线程安全的。访问var(读取或写入)的“存储复制”和“增加”之间的上下文切换可能会导致意外的程序行为。
【解决方案2】:

由于var++是后增量,基本上是这样的:

long foo(){
  long tmp = var;
  var++;
  return tmp;
}

如果您改用++var,它将返回递增后的值(因为它会在返回其值之前递增变量)。

【讨论】:

    【解决方案3】:

    foo() 将返回var 的当前值,而var 将增加。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-08
      • 1970-01-01
      • 2012-09-08
      • 2021-12-13
      • 2013-11-07
      • 2012-10-10
      相关资源
      最近更新 更多