我们来看看这个Hello World程序
#include <stdio.h>
int main(int argc, char ** argv) {
printf("Hello, World!");
const char* sFile = "/dev/stdout"; // or /proc/self/fd/0
const char* sMode = "w";
FILE * output = fopen(sFile, sMode);
//fflush(stdout) /* forces `correct` order */
putc('!', output); // Use output or stdout from stdio.h
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用output文件描述符编译时,输出为:
!Hello, World!
Run Code Online (Sandbox Code Playgroud)
使用输出stdout提供的文件描述符编译时stdio.h是按预期方式:
Hello, World!!
Run Code Online (Sandbox Code Playgroud)
我想,当putc用后者调用时,它会直接打印到stdout,当使用文件描述符时/dev/stdout,它将打开一个管道并打印到其中.我不确定.
这种行为更有趣,因为它不会覆盖'Hello'的第一个字符,而是将自己推入已经推送的字符串前面的行缓冲区的第一个位置.
从逻辑的角度来看,这是非常意外的.
谁能解释一下究竟发生了什么?
我正在使用
cc …
在阅读了这篇 Eric Lippert文章后,我明白如果我们将局部变量保持为未初始化,C#编译器就不喜欢它了.
当我不时遇到这个"问题"时,我查看了一些旧代码,并且能够清除大部分实际上不需要未初始化(SomeClass obj = null)局部变量的情况.
但我想出了一个我不知道如何重构代码的情况.
public void DoSomething(string foo) {
SomeClass obj; // = null;
try {
obj = SomeClass.CreateItem(target);
} catch(CustomException ex) {
// notify UI of error
}
if (obj != null) {
// do something with `obj`
}
}
Run Code Online (Sandbox Code Playgroud)
SomeClass.CreateItem可能因外部因素而失败.如果是,我想通知用户,如果不是,我想要执行一个动作.
C#编译器不希望我保持obj未初始化,所以我通常会分配null给它.
这感觉就像现在的'黑客',我的问题是:
上面的代码中是否存在设计缺陷?
如果有的话,在编译时如何处理引用,当我无法确定它们是否会在运行时指向现有对象时?