众所周知,GCC比Visual C ++更严格地实现C ++标准。 坦率地说,Visual C ++并不能很好地遵循C ++标准。
对于主要使用Visual C ++开发但需要代码可移植并至少使用GCC进行编译的开发人员而言,这一直是一个令人头痛的问题。
MSDN Nonstandard Behavior topic中记录了一些Visual C ++语言不端行为,实际上还有很多其他未记录的案例。
这篇文章的想法是针对GCC(最流行的C ++编译器)记录VC ++的所有已知兼容性问题。当使用Visual C ++编译某些代码片段而没有警告(W4级别)并且没有(使用GCC产生错误或警告)时会引发问题。
请注意,仅适用于标准C ++问题,Microsoft __super
或__forceinline
等特定语言扩展超出了范围。
建议的问题描述格式:
答案 0 :(得分:3)
这是一个非常广泛的问题,但这里有一些我遇到过的事情:
声明错误点:
#include <iostream>
struct S {
S(int) { std::cout << "Incorrect\n"; }
S(S const &) { std::cout << "Correct\n"; }
};
int s;
int main() {
S s(s);
}
输出应该是&#34;正确&#34;,但Visual Studio的(所有版本)输出是&#34;不正确&#34;。
复制分配和复制初始化的生成不正确:
#include <iostream>
struct B {
B &operator = (B &) { std::cout << "Correct\n"; return *this; }
template<typename T>
B &operator = (T &) { std::cout << "Incorrect\n"; return *this; }
};
struct D : B {};
int main() {
D d;
d = d;
}
我认为这是在Visual Studio 2012中修复的。在2012年之前,VS的输出是&#34;不正确&#34;。
两阶段名称查询:
#include <iostream>
static void foo(long) {
std::cout << "Correct\n";
}
template<typename T>
void bar(T t) {
foo(t);
}
static void foo(int) {
std::cout << "Incorrect\n";
}
int main() {
bar(1);
}
输出应该是&#34;更正&#34;,但Visual Studio(目前为止所有版本)的输出是&#34;不正确&#34;。
替代标记不起作用:
int main() <% %>
此程序应该编译并运行,但没有Visual Studio版本成功编译它。
for-loop initializer子句中的用户定义类型定义:
int main() {
for (struct {int a;} a = {0}; a.a < 10; ++(a.a)) {
}
}
这是合法的,但VS不允许。
所有这些在gcc和clang下正确编译和运行可以追溯到很多版本。 Gcc曾经遇到过两阶段查找的问题,但现在还没有。
答案 1 :(得分:1)
使用VC ++ 2013编译好的代码段:
struct X
{
template <class T> struct Z {};
template <> struct Z<int> {}; // Source of problem
};
产生GCC错误(4.7.2): error: explicit specialization in non-namespace scope
违反标准条款: 14.7.3 Explicit specialization, p.2 - An explicit specialization shall be declared in a namespace enclosing the specialized template.
解决方案:使用部分专精而不是显式专业:
struct X
{
template <class T, class MakeItPartial=void> struct Z {};
template <class MakeItPartial> struct Z<int, MakeItPartial> {};
};
或者如果可能的话,只需将其移动到封闭的命名空间范围:
struct X
{
template <class T> struct Z {};
};
template <> struct X::Z<int> {};