Visual Studio 2010:扩展/差异

3
Visual Studio 2010有一些默认启用的扩展/与C++标准存在差异。
这些差异可能会让人感到惊讶,并产生不同于其他行为的行为。VS以在模板代码验证方面极其宽松而著名,而被VS接受和编译的模板代码通常会被更加符合标准的编译器(CLang、Comeau、icc、gcc等)直接拒绝。
本问题的目的是为这些差异提供一个参考(因此使用FAQ标签)。
请每个差异提供一个答案(检查是否重复),并针对每个差异:
- 解释差异 - 告诉我们是否可以禁用它(如果可以,如何禁用) - 解释后果(除了简单的拒绝之外)
注意:C++0x是下一个标准,因此避免列出C++0x扩展,因为它们很快就会成为标准。
来自@Matteo Italia:Visual Studio Compliance Page

1
Visual Studio 的版本是哪个? - AnT stands with Russia
1
你需要指定一个版本。很多人发布的答案存在在VS2010中不存在的问题。 - Puppy
我有点不同意这被归为C++常见问题解答。 - sbi
哦,似乎没有人提到缺少两阶段查找。 - sbi
@sbi:我编辑了,如果您愿意,可以随意修改标签 :) - Matthieu M.
显示剩余5条评论
5个回答

6

首先,我会提供微软对这个主题的看法。

所有微软语言扩展可以在这里找到;还有一个页面列出了VC++不符合标准的语言领域


谢谢,我已经直接在问题中链接了合规问题 :) - Matthieu M.

4

默认情况下,编译器允许将临时对象绑定到非const引用。

解决方法:使用警告级别4。


有没有办法禁用这个?我真的对这个在重载解析期间与右值引用一起使用感到疑惑。 - Matthieu M.
1
有一个“禁用扩展”开关,但它会破坏Windows头文件。 :-( 它与rvalue引用参数一起使用时效果很好,因为这将更好地匹配临时值。 - Bo Persson

1

Visual C++不完全支持值初始化(或者说,在所有当前版本的Visual C++中存在错误,从Visual C++ 2005到Visual C++ 2010 SP1)。

几个 报告的 错误 关于这个问题(也可以参见另一个问题的此答案)。

结果:某些形式的代码应该对对象进行值初始化,但是会使对象或某些部分未初始化。

解决方法:不要依赖于值初始化。


0

不一致性: Visual Studio在第一次评估期间不绑定模板中的非依赖名称。

标准要求两个阶段的评估:

  • 第一步:检查基本模板的良好形式,绑定非依赖名称(包括重载分辨率)
  • 第二步:实例化适当的模板

禁用?它不受任何选项或开关的限制,它只是没有实现。

后果:

Visual Studio仅执行第二阶段,这会影响:

  • 仅在实例化时检测模板代码中的错误,因此最好尽早实例化编写的所有模板(将其视为编译单元测试)。
  • VS不会检测缺少templatetypename关键字
  • `模板之后声明的重载可能会被重载分辨率选择。 这不是很重要,因为恢复包含顺序将产生相同的结果。

这不是真的 - VS会在typename关键字上抛出异常,但不会在template上。 - Puppy
@DeadMG:从记忆中,一个人可以在类内部编写typedef T::iterator iterator;而不会被编译器打扰。 - Matthieu M.
这并不完全正确。然而,在某些情况下,只会生成警告,而标准合规需要一个错误。 - Paul Michalik

0

抱歉没有说明版本。我不知道还有多少人在使用旧版本的VS,但我希望大多数来到SO的用户都在使用更新的版本(VS 9 / VS 10)。 - Matthieu M.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接