类型通道用于格式说明符

3
我的老师通常说printf中每个格式说明符都有一个管道通道。也就是说,%d有一个管道通道,%f也有一个。他说,与每个格式说明符对应的表达式被评估并插入其管道中,最后从其中取出。他补充说,在gcc中,管道的填充(参数评估)是从右到左完成的,管道的清空(打印值)是从左到右完成的。
这个格式说明符的管道通道概念是什么?我在其他地方没有看到过,除了可能相关的pipe()函数。以下是一个相关的问题:fork() and pipes() in c
引用那个问题的答案,
管道是进程间通信的一种机制。由一个进程写入管道的数据可以被另一个进程读取。创建管道的原语是pipe()函数。这将创建管道的读取和写入端点。
编译器是否使用管道机制来执行printf语句?这是否与Linux中的管道有关?

我认为他所说的“管道”并不是指Unix管道的意思。那样太奇怪了。 - Thomas Padron-McCarthy
1个回答

2

你的讲师说的几乎都是错误的。我从未听说过“类型通道”或“管道通道”与C编程有任何关系。

参数传递通常涉及函数调用堆栈,可能还涉及处理器寄存器。它与Unix管道无关。

通常情况下,浮点参数使用的寄存器与整数不同。当printf说明符与它们的参数不匹配时(例如%d%f),这可能会导致特定的混淆。也许这就是你的讲师试图解释的内容。

还有一个不真实(或至少非常误导性)的观点是,函数参数的评估或消费不存在从右到左或从左到右的顺序。例如,如果你写了下面的代码:

printf("a and b returned %d and %d\n", a(), b());

这样做确实会打印出函数a()b()的返回值,但您无法知道哪个函数先被调用。编译器可能按任意顺序执行。

在许多版本的printf中有一个特殊的、很少使用的功能,允许您使用数字将printf格式说明符与它们的参数匹配。您可以在维基百科文章中了解更多信息(他们称之为“参数字段”)。但我怀疑您的讲师并不是在谈论这个。

是的,位置参数 n$ 功能很晦涩(也就是不太为人所知),尽管它得到了广泛支持。实际上,如果你使用 _printf_p() 而不是 printf(),甚至 Microsoft C 也支持它(尽管你必须为每个格式说明符提供位置信息)。我唯一记得看到这种位置参数功能被用于本地化/多语言支持,因为它非常有用,也可能是该功能存在的原因。 - Nominal Animal
1
他可能在谈论寄存器。 “管道”可能是他用来避免让学生困惑的非正式词汇。但他一直使用那个词,这让我感到困惑 :) 。而你的猜测是正确的。他试图解释当printf语句中存在参数不匹配或同一对象的多次更新时的未指定和/或未定义行为。谢谢。 - Cyriac Antony

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