【问题标题】:Type channels for format specifiers格式说明符的类型通道
【发布时间】:2018-03-18 07:54:29
【问题描述】:

我的老师通常说 printf 中的每个格式说明符都有一个管道通道。也就是说,%d 有一个管道通道,%f 有一个管道通道,依此类推。他说,对应于每个格式说明符的表达式被评估并插入到它的管道中,最后从中取出。他补充说,至少在 gcc 中,管道的填充(参数评估)是从右到左完成的,而管道的清空(打印值)是从左到右完成的。

格式说明符的管道通道的概念是什么? 除了可能相关的 pipe() 函数之外,我在其他任何地方都看不到它。以下是相关问题:fork() and pipes() in c

引用该问题的答案,

管道是一种用于进程间通信的机制。一个进程写入管道的数据可以被另一个进程读取。创建管道的原语是 pipe() 函数。这将创建管道的读取和写入端。

编译器是否使用管道机制以这种方式执行 printf 语句?这与linux中的管道有关吗?

【问题讨论】:

  • 我不认为他指的是 Unix 管道意义上的管道。那太奇怪了。

标签: c format-specifiers


【解决方案1】:

几乎你的导师所说的一切都是错误的。我从未听说过与 C 编程有关的术语“类型通道”或“管道通道”。

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

通常情况下,浮点参数使用与整数不同的寄存器传递。当您在 printf 说明符和它们的参数之间存在不匹配时,这可能会导致特别的混乱(例如,%d%f)。也许这就是你的导师想要解释的。

在评估或使用函数参数时暗示存在任何从右到左或从左到右的顺序也是不正确的(或至少具有高度误导性)。例如,如果你要写

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

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

printf 的许多版本中有一个特殊的、很少使用的功能,它允许您使用数字来匹配 printf 格式说明符及其参数。您可以在the Wikipedia article(他们称之为“参数字段”)中阅读有关此内容的一些信息。但我怀疑你的导师是否在谈论这个。

【讨论】:

  • 是的,n$ 定位功能是晦涩难懂的(因为它根本不为人所知),尽管它得到了广泛的支持。事实上,如果您使用_printf_p() 而不是printf(),它甚至被Microsoft C 支持(尽管您必须为每个格式说明符提供位置信息)。我记得看到使用此位置参数功能的唯一地方是在本地化/多语言支持中,它有很大帮助,这可能是该功能首先存在的原因。
  • 他很可能在谈论寄存器。 “管道”可能是他用来避免混淆学生的非正式词。但是他一直在使用那个让我感到困惑的词:)。你的猜测是正确的。当 printf 语句中存在参数不匹配或同一对象的多次更新时,他试图解释未指定和/或未定义的行为。谢谢
猜你喜欢
  • 2012-11-06
  • 1970-01-01
  • 2020-05-23
  • 1970-01-01
  • 2023-03-10
  • 2020-10-07
  • 1970-01-01
  • 2023-04-10
  • 2017-11-23
相关资源
最近更新 更多