gcc和turbo C的输出差异

为什么使用两个编译器gccturbo c编译代码时产生的输出有所不同。

 #include  int main() { char *p = "I am a string"; char *q = "I am a string"; if(p==q) { printf("Optimized"); } else{ printf("Change your compiler"); } return 0; } 

我在gcc上得到了"Optimized" ,在turbo c上得到了"Optimized" "Change your compiler" 。 为什么?

您的问题已被标记为C以及C ++。 所以我会回答这两种语言。

[C]

来自ISO C99( Section 6.4.5/6

It is unspecified whether these arrays are distinct provided their elements have the appropriate values.

这意味着unspecified pq是否指向相同的字符串文字。 在gcc情况下,他们都指向"I am a string" (gcc优化你的代码)而在turbo c它们不是。

未指定的行为:使用未指定的值或本国际标准提供两种或更多种可能性的其他行为,并且在任何情况下都不会对其进行任何进一步的要求


[C++]

来自ISO C ++ – 98( Section 2.13.4/2

Whether all string literals are distinct(that is, are stored in non overlapping objects) is implementation defined.

在C ++中,您的代码调用实现定义的行为。

实现定义的行为:Unspeci fi ed行为,其中每个实现都documents如何做出选择


另见这个问题。

由于您的字符串文字是一个常量表达式,即您不应该通过指针修改它,因此将它存储在内存空间中两次没有任何实际意义。 作为一个较新的编译器,gcc默认合并文字,而Turbo C则不合并。 这是gcc支持具有const数据概念的新语言标准的一个标志。

请忘记与答案相同的答案

“这是因为Turbo C完全是老而且他们不能这样做,因为它必须是快速的,但GCC完全是新的和RAD,这就是为什么它这样做!”

两个编译器都支持合并字符串常量作为选项。 GCC选项( -fmerge-constants )在优化级别打开,而Turbo C选项( -d )在默认情况下关闭。 如果您使用的是TCC IDE,请转到Options|Compiler...|Code Generation..并选中“ Duplicate strings merged ”。

从gcc手册页:

-fmerge常数

尝试跨编译单元合并相同的常量(字符串常量和浮点常量)。

如果汇编器和链接器支持,则此选项是优化编译的缺省选项。 使用-fno-merge-constants可以禁止此行为。

在-O,-O2,-O3,-Os等级启用。

因此输出。

Turbo C针对快速编译进行了优化,因此它没有任何可以降低速度的function。 识别重复的字符串将是一个减慢,即使只是次要的。

如果认为合适,编译器可以保留两个相同文字的副本。 找出是否是这种情况可能是该计划的重点。

在过去的好时光中,汇编程序将所有文字保存在文字池中,修补文字池是一种公认​​的(如果不是批准的)在整个程序中修改“常量”的技术。

如果在某种程度上编译器允许在这种情况下*p = 'H'; 那么就会产生重要的行为差异。

历史脚注:由于地址小于浮点数字常量,FORTRAN用于处理浮点常量,就像C处理字符串一样。 由于内存是珍贵的,相同的常量将被分配相同的空间。 此外,参数传递始终通过引用完成。 这意味着如果将数字常量传递给修改其参数的过程,那么“常量”的其他出现将改变值。

因此,古老的说法是:“变量不会;常数不会。”

顺便说一下,有没有人注意到Turbo C 2.0 printf中的错误,当使用像“%1.1f”这样的格式来打印99.99(输出00.0)这样的数字时会出现问题? 在2.01中修复,它让我想起了Windows 3.1计算器错误。