在C/C++上,基本上什么是编译器依赖的东西?

onl*_*man 1 c c++ compiler-construction

什么任务,功能,执行因编译器而异?我知道这段代码依赖于编译器 -

#include <stdio.h>
#define PRODUCT(x)(x*x)
int main()
{
int i=3,j,k;
j=PRODUCT(i++);
k=PRODUCT(++i);
printf("\n%d %d",j,k);
}
Run Code Online (Sandbox Code Playgroud)

下面给出了一些垃圾,而其他的则是固定值 -

#include <stdio.h>
int main()
{
int i=5,j=10;
printf("%d,%d");
}
Run Code Online (Sandbox Code Playgroud)

因此执行顺序因编译器而异.这些模棱两可的课程是否有资格参加考试?

bdo*_*lan 12

如果您想要完整列表,则需要查看标准文档.在C标准中,定义了两种类型的"编译器相关"问题:

  • 实现定义的行为:行为可能因编译器而异,但编译器必须提供某种一致的行为,并且必须记录此行为.一个例子,直接来自标准:"实现定义行为的一个例子是当有符号整数向右移位时高阶位的传播." 换句话说,-1 >> 1编译器之间的结果可能不同,但编译器必须保持一致.
  • 未定义的行为:所有投注均已关闭.当你遇到未定义的行为时,任何事情 - 我的意思是任何事情都可能发生.您的代码就是一个很好的例子 - 您可以在没有插入序列点的情况下修改单个变量两次(违反ISO/IEC 9899:1999(E)§6.5的约束).在第二个中,您缺少参数(根据§7.19.6.1/ 2的未定义行为).根据严格的标准阅读,在这种情况下编译器通过你的鼻子召唤恶魔是完全合理的.

您还需要注意约束违规.通常,标准规定诸如"[ main]的内容应定义为int[...]" 的返回类型(§5.1.2.2.1/ 1).这相当于"如果main使用其他 类型的返回类型声明int,则程序的行为未定义".(见§4.2,标准明确赞同此解释)

你不应该在考试中问这些问题; 如果你是,你应该简单地声明程序的行为是未定义的(或实现定义的).需要注意的是一些实现定义的行为是有极限的-例如,该值sizeof(int)是实现定义的,但你知道,sizeof(int) >= sizeof(short) && sizeof(int) <= sizeof(long)-所以仅仅有任何实现定义的行为并不意味着你不能说对程序做什么东西.