当取消引用和后递增函数指针的指针时,首先会发生什么?

发布于 2024-10-19 08:35:15 字数 275 浏览 6 评论 0原文

给定以下代码:

 typedef void (*Thunk)();
 Thunk* gFP;

 void foo(){ printf("Foo "); *gFP(); };
 void bar(){ printf("Bar ");

 Thunk Codex[] = { foo, bar };

 gFP = Codex;

 (*gFP++)();

函数调用发生在增量之前还是之后?
即:这会打印“Foo Foo Foo ...”或“Foo Bar”吗?

Given this code:

 typedef void (*Thunk)();
 Thunk* gFP;

 void foo(){ printf("Foo "); *gFP(); };
 void bar(){ printf("Bar ");

 Thunk Codex[] = { foo, bar };

 gFP = Codex;

 (*gFP++)();

Does the function call happen before or after the increment?
i.e: Will this print "Foo Foo Foo ..." or "Foo Bar"?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

世界等同你 2024-10-26 08:35:15

这只是我个人的看法。我并不 100% 相信这是正确的。
所以,如果我的回答有错误,请原谅我。

C99 6.5.2.2/10函数调用说:

评估顺序
功能指示符,实际值
参数和子表达式
实际参数未指定,
但之前有一个序列点
实际的调用。

C99 6.5.2.4/2 后缀递增和递减运算符 说:

更新存储的副作用
操作数的值应发生
上一个和下一个之间
序列点。

后增量运算符的副作用是在
下一个序列点。
假设表达式f( x )
我认为在计算fx之后有一个序列点,并且
在函数调用之前。
所以,gFP++的副作用会在函数调用之前完成,
问题中的代码预计会打印 Foo Bar

编辑:
我删除了 C99 和 C++ 中附录 C 中的引号,并添加了来自
C99。
之前的引述可能对这个问题含糊其辞。

This is just my personal view. I'm not 100% convinced that this is correct.
So, please forgive me if my answer is wrong.

C99 6.5.2.2/10 Function calls says:

The order of evaluation of the
function designator, the actual
arguments, and subexpressions within
the actual arguments is unspecified,
but there is a sequence point before
the actual call.

C99 6.5.2.4/2 Postfix increment and decrement operators says:

The side effect of updating the stored
value of the operand shall occur
between the previous and the next
sequence point.

The side effect of post increment operator is completed somewhere before the
next sequence point.
Assuming the expression f( x ),
I think there is a sequence point after the evaluation of f and x, and
before the function call.
So, the side effect of gFP++ will be completed before the function call,
and the code in the question is expected to print Foo Bar.

Edit:
I removed the quotes from Annex-C in C99 and C++, and added the quotes from
C99.
Probably previous quotes were indistinct regarding the question.

新雨望断虹 2024-10-26 08:35:15

首先发生取消引用。这与任何其他后增量相同:使用原始值。

例如,请参阅关于序列点的后增量

但是,您的问题似乎是 foo() 内部使用的函数指针是否会调用 foo() 或 bar() 。

http://newsgroups.derkeiler.com/ Archive/Comp/comp.std.c/2009-10/msg00053.html 是 comp.std.c 中的一个讨论,标题为“序列点问题”,正是针对这一点进行了争论。我认为双方没有达成共识,但双方都有很好的论据。

根据我之前阅读的标准,这将调用未定义的行为。

对函数的调用充当序列点,但附录 C 仅表示它充当相对于作为参数传入的表达式的序列点 —— 它们保证被求值,但其他任何东西都不一定会被求值(在 f( i++) + g(j++) 访问 g() 中的 if() 中的 j code> 调用未定义的行为。)

但是,6.5.5.2 (p 10) 说:

后面有一个序列点
功能指示符的评估
和之前的实际参数
实际的调用。

这意味着它确实++进行排序。

The dereference happens first. This is the same thing as any other post-increment: the original value is used.

See, for instance, Post Increment with respect to Sequence Points

However, your question seems to be whether the function pointer use inside of foo() will call foo() or bar().

http://newsgroups.derkeiler.com/Archive/Comp/comp.std.c/2009-10/msg00053.html is a discussion in comp.std.c with the header "sequence point problem" that argues over precisely this point. I don't think it came to a consensus, but there were good arguments on both sides.

By my previous reading of the standard, this would invokes undefined behavior.

The call to a function acts as sequence point, but appendix C only says it acts as a sequence point relative to the expressions passed in as parameters -- they are guaranteed to be evaluated, but nothing else necessarily will (in f(i++) + g(j++) accessing either i in g() or j in f() invokes undefined behavior.)

However, 6.5.5.2 (p 10) says:

There is a sequence point after the
evaluations of the function designator
and the actual arguments but before
the actual call.

which means that it does sequence the ++.

弥枳 2024-10-26 08:35:15

运算符优先级表 显示 C 的运算顺序。

在您的示例中, gFP++ 具有最高优先级,其次是 *gFP

但是,直到所有其他操作完成后才会完成增量。

所以你最终会得到的是对 gFP 进行解引用操作,然后是函数调用,然后 gFP 的值递增。

所以你最终会出现堆栈溢出。

The operator precedence table shows the order of operations for C.

In your example, gFP++ has the highest precedence, followed by *gFP

However, the increment is not done until all other operations have completed.

So what you will end up with is the dereference operating on gFP, then the function call, then the value of gFP being incremented.

So you will end up with a stack overflow.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文