英文:
Is it possible to write a strictly conforming C program that outputs to the display?
问题
根据 ISO/IEC 9899:2017:
“一个严格遵守的程序应该仅使用本文档中指定的语言和库的特性。**它不应该产生依赖于未指定、未定义或实现定义行为的输出,**也不应该超过最小的实现限制。”
然而,几页之后,它提到:
“活动位置是显示设备上下一个由 fputc
函数输出的字符将出现的位置。将打印字符(由 isprint
函数定义)写入显示设备的意图是在活动位置显示该字符的图形表示,然后将活动位置前进到当前行的下一个位置。写入的方向是与区域设置相关的。如果活动位置位于行的最后位置(如果有的话),则显示设备的行为是未指定的。
由于似乎没有办法判断活动位置是否位于行的最后位置,因此无法在不引发未指定行为的情况下输出到显示设备,因此不可能编写一个严格遵守的程序。这是一个错误还是我漏掉了什么?"
英文:
According to ISO/IEC 9899:2017:
> A strictly conforming program shall use only those features of the language and library specified in this document. It shall not produce output dependent on any unspecified, undefined, or implementation-defined behavior, and shall not exceed any minimum implementation limit.
However, a few pages later, it says:
> The active position is that location on a display device where the next character output by the fputc
function would appear. The intent of writing a printing character (as defined by the isprint
function) to a display device is to display a graphic representation of that character at the active position and then advance the active position to the next position on the current line. The direction of writing is locale-specific. If the active position is at the final position of a line (if there is one), the behavior of the display device is unspecified.
Since there doesn't seem to be any way to tell if the active position is at the final position of a line, then there is no way to output to the display device without risking invoking unspecified behavior, and as such it's impossible to write a strictly conforming program. Is this a mistake or is there something I'm missing?
答案1
得分: 5
由于似乎没有办法判断活动位置是否位于行的最终位置,因此在不引发未指定行为的情况下无法向显示设备输出。
同意,但严格遵守的程序的要求并不是要避免所有未指定的行为,而是
它不应该产生依赖于 [未指定行为等] 的输出
产生的输出是程序的一个函数。 输出被定向到的设备的行为是设备的一个函数,与输出本身分开,该行为是否被指定或定义清楚与程序是否严格遵守无关。
是否可能编写一个严格遵守的 C 程序,以将输出发送到显示设备?
一个严格遵守的程序无法知道或控制其产生的任何输出是否被定向到(一个)显示器。 但当它被定向到时,这并不会影响程序的符合性。 从这个意义上说,是的,可能编写一个严格遵守的程序,将输出发送到显示设备。 这样做并不比编写一个将输出发送到常规文件的严格遵守的程序更难。
英文:
> Since there doesn't seem to be any way to tell if the active position is at the final position of a line, then there is no way to output to the display device without risking invoking unspecified behavior
Agreed, but the requirement on a strictly-conforming program is not that it avoid all unspecified behavior, but rather that
> It shall not produce output dependent on [unspecified behavior et. al]
The output produced is a function of the program. The behavior of a device to which that output is directed is a function of the device, separate from the output itself, and whether that behavior is specified or well defined is not relevant to whether the program conforms strictly.
> Is it possible to write a strictly conforming C program that outputs to the display?
It is not possible for a strictly-conforming program to know or control whether any output it produces is directed to the (a) display. But when it is, that does not impact the program's conformance. In that sense, yes, it is possible to write a strictly conforming program that outputs to a display device. Doing so is not any harder than writing a strictly conforming program that outputs to a regular file.
答案2
得分: 3
很多C标准的方面都相当“模糊”,并且并没有认真尝试以明确的方式描述每一个可能的C程序是严格符合规范的,还是严格不符合规范的。实际上,仅凭文本是不可能确定任何特定源代码是否是一个严格符合规范的C程序的。
考虑以下程序:
#include <stdio.h>
int main(void)
{
printf("1") + printf("2");
printf("\n");
return 0;
}
上述程序可能是:
- 一个严格符合规范的C程序,用于输出任意倍数的3。
- 一个非便携程序,用于输出任意倍数的4。
- 一个非便携程序,用于输出任意倍数的7。
- 一个严格符合规范但有缺陷的程序,用于输出任意倍数的8。
- 一个非便携且有缺陷的程序,用于输出任意倍数的8。
如果一个程序被指定为在显示器上产生特定图像的程序,而该程序被指定为将特定字符序列发送到stdout,无论其产生的后果如何,即使所选择的字节序列是为了在特定系统上运行时产生特定图像,该程序也可能是严格符合规范的。如果指定为产生特定图像的程序输出相同的字节序列,它将是一个非便携程序,用于在特定系统上产生特定图像。
一个用于使各种组件(如插头和插座)协同工作的标准会对插头、插座、插头测试器和插座测试器分别进行规定,以便:
-
不存在任何组合的插头和插头测试器,使得插头会被拒绝,除非插头或测试器中的一个是明确不符合规范的。
-
不存在任何组合的插头和插头测试器,使得插头会被拒绝,除非插头或测试器中的一个是明确不符合规范的。
-
不存在任何组合的插头、插座、插头测试器和插座测试器,使得插头和插座通过各自的测试,但插头不能与插座配合使用,除非至少一个测试器是明确不符合规范的。
请注意,没有必要将宇宙明确划分为符合规范的插头和不符合规范的插头,或者对插座、插头测试器或插座测试器做出相同的划分。如果有些事物无法可靠地归类为符合规范的插头或不符合规范的插头,但插头测试器会明确要求接受它们,那么模糊性的存在不会造成特别的问题,只会增加符合规范的成本。良好的标准应该努力容忍最实际的模糊程度,而不是试图完全消除所有的模糊性。
不幸的是,C标准试图对一切使用一个规范,既不试图消除模糊性,也不做任何对此的让步。相反,该标准依赖于实现来运用常识来决定如何处理构造,而不考虑它们是否“技术上”严格符合规范,从而避免了标准必须明确说明它们是否符合规范的需要。
英文:
Many aspects of the C Standard are rather "hand-wavy", and do not seriously attempt to unambiguously characterize every possible C program as being unambiguously strictly conforming or unambiguously not strictly conforming. Indeed, it's impossible to determine whether any particular source text is a strictly conforming C program based solely on the text.
Consider the program:
#include <stdio.h>
int main(void)
{
printf("1") + printf("2");
printf("\n");
return 0;
}
the above could be:
- A Strictly Conforming C Program to output an arbitrary multiple of 3.
- A non-portable program to output an arbitrary multiple of 4.
- A non-portable program to output an arbitrary multiple of 7.
- A Strictly Conforming but buggy program to output an arbitrary multiple of 8.
- A non-portable and buggy program to output an arbitrary multiple of 8.
If a program which is supposed to produce a particular image on on a display is specified as sending a certain sequence of characters to stdout, with whatever consequences result, then such a program could be strictly conforming even if the sequence of bytes was chosen because it will produce a particular image when run on a particular system. If the program which specified as producing that particular image outputs the same sequence of bytes, it would be a non-portable program to produce that particular image on a particular system.
A standard for things that are supposed to work together, such as plugs and sockets, would have separate specifications for plugs, sockets, plug testers, and socket testers, such that:
-
It would be impossible for any combination of plug and plug tester to exist, such that the plug would be rejected, unless either the plug or tester was unambiguously non-conforming.
-
It would be impossible for any combination of plug and plug tester to exist, such that the plug would be rejected, unless either the plug or tester was unambiguously non-conforming.
-
It would be impossible for any combination of plug, socket, plug tester, and socket tester to exist, such that the plug and socket pass their respective tests, but the plug wouldn't work with the socket, unless at least one of the testers was unambiguously non-conforming.
Note that there is no need to unambiguously partition the universe unambiguously into things that are conforming plugs and things that are not conforming plugs, nor likewise for sockets, plug testers, or socket testers. If there are some things that cannot be reliably classified as being conforming plugs or not being conforming plugs, but plug testers would unambiguously be required to accept them, the presence of ambiguity wouldn't pose a particular problem beyond increasing the cost of conformance. Good standard should seek to tolerate whatever level of ambiguity would be most practical, rather than trying to eliminate all ambiguity altogether.
The C Standard, unfortunately, tries to use one specification for everything, without either trying to eliminate ambiguity nor make any accommodations for it. Instead, the Standard falls back on a hand-waving reliance upon implementations to exercise common sense in deciding how to process constructs without regard for whether they are "technically" strictly conforming, thus avoiding any need for the Standard to unambiguously say whether they are or not.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论