C++ APUE第7章中的hello world退出,代码为0
APUE第7章说,该代码段将以示例中0 13以外的退出代码退出。但它在我的计算机上以代码0退出:C++ APUE第7章中的hello world退出,代码为0,c++,c,macos,unix,C++,C,Macos,Unix,APUE第7章说,该代码段将以示例中0 13以外的退出代码退出。但它在我的计算机上以代码0退出: #include <stdio.h> main() { printf("hello, world\n"); } 编译和运行环境: 达尔文崔晓晨-MacBook-Pro.local 17.4.0达尔文内核版本17.4.0:Sun Dec 17 09:19:54 PST 2017;根目录:xnu-4570.41.2~1/RELEASE_X86_64 X86_64 Gcc版本
#include <stdio.h>
main()
{
printf("hello, world\n");
}
编译和运行环境:
达尔文崔晓晨-MacBook-Pro.local 17.4.0达尔文内核版本17.4.0:Sun Dec 17 09:19:54 PST 2017;根目录:xnu-4570.41.2~1/RELEASE_X86_64 X86_64
Gcc版本:
♪ apue.3e git:master gcc-v
配置为:-prefix=/Library/Developer/CommandLineTools/usr-配置为gxx include dir=/usr/include/c++/4.2.1
苹果LLVM版本9.0.0-900.0.39.2
目标:x86_64-apple-darwin17.4.0
线程模型:posix
InstalledDir:/Library/Developer/CommandLineTools/usr/bin
旅游指南章节有误。C语言中的主要功能是在没有返回语句的情况下用标准来保证返回零,如果我们考虑的标准不超过20年 < P>旅行APUE章节是错误的。C语言中的主要功能是在没有返回语句的情况下用标准返回零,如果我们考虑标准不超过20年 ApUE试图说明一个真实的现象,并且仍然有可能用改进的程序来观察这个现象。 通常,当一个函数声明返回一个值(即返回类型不是void)时,它的返回值是不确定的,并且观察该值的程序具有未定义的行为。实现该未定义行为的一种常见方法是,函数的返回值等于函数中最后一次调用的返回值,因为该值仍在返回值寄存器中。APUE试图通过从main端部跌落来证明这一点,但由于C99,有一条关于从main端部跌落的特殊规则,该规则表示这表现为main已正确返回0。许多编译器甚至在C89模式下也应用了这个规则,因为在C89中它是未定义的,所以他们可以做任何他们喜欢的事情 因此,要观察APUE希望您观察的现象,您需要使用main以外的函数,还需要采取措施防止过程间分析,例如将程序拆分为两个翻译单元,然后不使用链接时间优化
/* file1.c */
#include <stdio.h>
int print_hello(void)
{
printf("hello world\n");
}
/* file2.c */
#include <stdio.h>
extern int print_hello(void);
int main(void);
{
int n = print_hello();
printf("print_hello returned %d\n", n);
return 0;
}
请记住,这个程序确实有未定义的行为。在具有不同呼叫约定(例如SPARC)的计算机上,它可能打印垃圾号;如果我允许进行过程间优化,编译器可能会推断出程序没有未定义行为的唯一方法是它从未运行过,因此不会为它发出任何代码
如果从未使用print_hello返回的值,程序将不会有未定义的行为。这是该语言中的另一个特例,因为它可以向后兼容在void返回类型出现之前编写的代码。APUE试图说明一个真实的现象,并且仍然可以通过修改程序来观察这种现象 当返回值为未定义的值时,程序返回的值不是未定义的值,而是未定义的值。实现该未定义行为的一种常见方法是,函数的返回值等于函数中最后一次调用的返回值,因为该值仍在返回值寄存器中。APUE试图通过从main端部跌落来证明这一点,但由于C99,有一条关于从main端部跌落的特殊规则,该规则表示这表现为main已正确返回0。许多编译器甚至在C89模式下也应用了这个规则,因为在C89中它是未定义的,所以他们可以做任何他们喜欢的事情 因此,要观察APUE希望您观察的现象,您需要使用main以外的函数,还需要采取措施防止过程间分析,例如将程序拆分为两个翻译单元,然后不使用链接时间优化
/* file1.c */
#include <stdio.h>
int print_hello(void)
{
printf("hello world\n");
}
/* file2.c */
#include <stdio.h>
extern int print_hello(void);
int main(void);
{
int n = print_hello();
printf("print_hello returned %d\n", n);
return 0;
}
请记住,这个程序确实有未定义的行为。在具有不同呼叫约定(例如SPARC)的计算机上,它可能打印垃圾号;如果我允许进行过程间优化,编译器可能会推断出程序没有未定义行为的唯一方法是它从未运行过,因此不会为它发出任何代码
如果从未使用print_hello返回的值,程序将不会有未定义的行为。这是该语言中的另一个特例,因为它可以向后兼容在void返回类型出现之前编写的代码。APUE现在已经相当旧了,您显示的代码不再是真正有效的C代码。唯一的问题是,自从C99标准以来,main中不需要显式返回。@Someprogrammerdude但即使我用-std=c89编译程序,程序st
我将以代码0退出,因为它是UB。任何值都是可能的。在你的情况下是0。如果你让main变得不那么琐碎,它很可能是其他东西。不要试图解释为什么UB会给出一个特定的结果pointless@P__J__我不同意试图找出UB给出特定结果的原因是毫无意义的。您必须记住,它可能会在不同的CPU或编译器上产生完全不同的结果,但了解为UB的特定实例生成的机器代码的实际用途对于深入理解语言和硬件是很有价值的。@zwol不在学习的这个阶段。现在它只会带来混乱。APUE现在已经相当旧了,您显示的代码不再是真正有效的C代码。唯一的问题是,由于C99标准,main中不需要显式返回。@Someprogrammerdude,但即使我用-std=c89编译程序,该程序仍然以代码0退出,因为它是UB。任何值都是可能的。在你的情况下是0。如果你让main变得不那么琐碎,它很可能是其他东西。不要试图解释为什么UB会给出一个特定的结果pointless@P__J__我不同意试图找出UB给出特定结果的原因是毫无意义的。您必须记住,它可能会在不同的CPU或编译器上产生完全不同的结果,但了解为UB的特定实例生成的机器代码的实际用途对于深入理解语言和硬件是很有价值的。@zwol不在学习的这个阶段。现在只会带来混乱。