多年来我一直没有用C ++编写代码。我最近发现,在那些年里它发生了巨大变化。我不确定我是否喜欢这些变化,但这是另一个讨论。
我仍然有一些C ++代码敲我的硬盘。如果我把它拿出来并尝试用一个不错的新C ++编译器编译它,比如说最新版本的g ++,它会编译吗?没有警告(假设它之前没有警告编译)?
我最近搞砸了一些VC ++ 2010,并发现了一些我期望工作的东西不起作用,并且在我尝试使用NULL时根据上下文获得了不同的消息。但是在该代码的一部分中,我使用了NULL,甚至没有警告。
答案 0 :(得分:13)
这取决于。通常较新的编译器更符合标准,因此在早期编译器上编译的许多构造在没有修复的情况下现在无法编译。例如:
for( int i = 0; ... );
i++;
在Visual C ++ 7中编译,但在Visual C ++ 9中编译。
答案 1 :(得分:8)
一般来说,是的,它是向后兼容的。然而,魔鬼在细节中。您可能会发现约定发生变化的情况,或者特定的库会进入或不使用。
答案 2 :(得分:7)
NULL是一个宏 - 更喜欢使用0(或nullptr in C++0x)。
不确定代码的年龄,但Visual C ++ v6受到限制,导致代码无法在较新的编译器上编译。 VS2005及以上版本要好得多(在同期C ++标准中更为正确)。
但是,我不认为编译旧代码会带来大量工作。我已经从VC6完成了一些非常重要的端口 - > VS2005,大部分时间都是几小时,而不是几天。也许一旦文化冲击消退,这似乎并不那么令人生畏。真的,VC ++ 10非常好。答案 3 :(得分:4)
这取决于你要比较的内容。
C ++ 0x与C ++ 03/98几乎向后兼容。可能会有一些不明显的角落情况发生了变化,但您不太可能遇到它们。 但是,当语言 first 标准化时,发生了很多变化,这意味着C ++ 98并不完全(但几乎)与预标准C ++兼容。
但更有可能的是,你所遇到的不是C ++向后兼容性的问题,而只是编译器变得更加严格。他们在遵循标准方面变得更好,并且不再允许许多早期常见的非标准技巧。最有可能的是,您的旧代码从不有效的C ++,但是因为编译器过去偏离了标准,所以很有用。
答案 4 :(得分:3)
语言本身自1998年标准化以来没有改变。成语已经改变,编译器既改进了对标准的支持,又对非标准代码更加严格,但编译的任何符合标准的C ++代码都是过去应该今天仍然编制。依赖于非标准编译器功能或怪癖的代码可能不起作用,但编译器通常提供命令行选项,使它们接受以前版本的同一编译器接受的非标准代码。
NULL是在<cstddef>
中定义的宏。其他标准头文件可能包含该头文件作为实现细节,因此通常可以在不明确包含<cstddef>
的情况下使用NULL,但依赖于此文件始终是不可移植的。只要包含其标题就可以使用NULL,但在惯用的C ++中只使用0是首选。
答案 5 :(得分:2)
所有版本的C ++都应向后兼容。
虽然可能存在一些可能存在问题的异常情况,例如在C ++ 0x中的destructos上没有例外(尽管尚未确定)。
答案 6 :(得分:2)
嗯,我知道当我们升级到VS 2005时,我们很多旧的VS6代码开始抛出大量警告(当然,每个人都应该工作时会发出完全警告)。大多数是好的事情,警告潜在的信息丢失,警告某些类型可能是64位而不是像旧代码可能期望的32位等。
对于你的NULL的具体例子,那天甚至不是真正的标准C。每个编译器只有一个#define
,它将它设置为0.这些天通常被认为对just use 0更正确(和清晰)。
答案 7 :(得分:2)
较新的C ++标准澄清了事情,然后对哪些用法“更正确”或接受进行了解释,因此我希望得到警告。其他一些决定会改变可以做或不做的事情,所以我也会期待错误。我遇到过相同的情况,我不得不调整代码以便编译。这不是很多,但这考虑到了我对C ++的了解。一般来说,你应该遇到很多问题。
还有其他的事情。例如,并非所有编译器都实现了C ++标准的整个规则,或者它们存在错误。当您使用编译器时,其中一些错误或缺少的功能可能会被忽略不计地传递给您的编译器,但可能会在同一编译器的未来版本中导致错误。
答案 8 :(得分:2)
这是我们制定标准的主要原因。您不必担心兼容性,您只需告诉编译器将代码编译为C ++ 98(或2003)。
不幸的是,MSVC在支持C ++标准方面非常糟糕。它正在慢慢变好(这就是旧代码无法编译的原因,因为它不应该首先编译)。
答案 9 :(得分:0)
如果您使用过各种库的旧版本(如Boost),则会遇到一些问题。
答案 10 :(得分:0)
与sharptooth的答案非常相似,有些旧的C和C ++代码需要/ ZC:forScope- set(即不强制执行for循环范围)。 e.g。
int myfunc(int x, int y, int z)
{
int j;
for (int i=0; i <= 10; i++)
{
if (f(i) == 0)
break;
}
j = i;
for (i=0; i <= 10; i++)
{
if (g(i) == 0)
break;
}
if (i > j)
return j;
return i;
}
这种类型的东西在很老的代码中很常见,其中字节成本和可变重用是常见的。
答案 11 :(得分:0)
略有随机,但关键字export
正在从标准中删除。因此,以前符合标准的代码使用的export
现在是非法的。当然,很少有编译器甚至开始实现该关键字。