将源代码从 Visual C++ 移植到 GCC 都有哪些陷阱[关闭]
Posted
技术标签:
【中文标题】将源代码从 Visual C++ 移植到 GCC 都有哪些陷阱[关闭]【英文标题】:What are pitfalls of porting source code from Visual C++ to GCC [closed]将源代码从 Visual C++ 移植到 GCC 有哪些陷阱[关闭] 【发布时间】:2014-08-26 22:55:13 【问题描述】:众所周知,GCC 对 C++ 标准的实现比 Visual C++ 严格得多。 坦率地说,Visual C++ 只是没有很好地遵循 C++ 标准。
对于主要使用 Visual C++ 进行开发但需要至少使用 GCC 进行代码可移植和编译的开发人员来说,这一直是令人头疼的问题。
一些 Visual C++ 语言不当行为记录在 MSDN Nonstandard Behavior topic 中,实际上还有很多其他未记录的案例。
这篇文章的目的是记录所有已知的 VC++ 与 GCC(最流行的 C++ 编译器)的兼容性问题。当某些代码 sn-p 使用 Visual C++ 编译而没有警告(W4 级别)并且不使用 GCC(产生错误或警告)时,会引发问题。
请注意,它仅适用于标准 C++ 问题,__super
或 __forceinline
等 Microsoft 特定语言扩展超出范围。
问题描述的建议格式:
代码 sn-p(使用 Visual C++ 编译成功) GCC 错误或它产生的警告 要重现的两个编译器版本 对违反 C++ 标准语句的引用(可选,以后可以添加) 解决方案(如何更改代码以使 VC++ 和 GCC 都成功编译)【问题讨论】:
坚持使用标准 C++,您很可能会避免这些陷阱。 @40two 即使坚持标准 C++ 也不会很好地工作。正如 OP 所说,Visual Studio 在遵循标准方面真的很糟糕,并且创建适用于两者的代码是实际标准的受限集。那或一堆'#ifdef MSVC' @Smith_61 请注意我的陈述中的“最可能”一词。 这个问题太宽泛了,不适合 SO。为了得到完整的回答,需要为每个不符合标准的功能发布代码 sn-ps 和由此产生的错误消息以及替代解决方案。需要一个完整的网站或 wiki 来解决这个主题。 无法以 Stack Overflow 格式正确回答的问题不在主题范围内。您要求发布数十个甚至数百个答案,但没有一个答案是正确的。 【参考方案1】:这是一个相当广泛的问题,但我遇到了一些问题:
声明点错误:
#include <iostream>
struct S
S(int) std::cout << "Incorrect\n";
S(S const &) std::cout << "Correct\n";
;
int s;
int main()
S s(s);
输出应该是“正确的”,但 Visual Studio(所有版本)的输出是“不正确的”。
复制分配和复制初始化的生成不正确:
#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 的输出是“不正确的”。
两阶段名称查找:
#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);
输出应该是“正确的”,但 Visual Studio(到目前为止的所有版本)的输出是“不正确的”。
替代令牌不起作用:
int main() <% %>
该程序应该可以编译并运行,但没有任何版本的 Visual Studio 可以成功编译它。
for-loop 初始化子句中用户定义的类型定义:
int main()
for (struct int a; a = 0; a.a < 10; ++(a.a))
这是合法的,但 VS 不允许。
所有这些都在 gcc 和 clang 下正确编译和运行,可以追溯到很多版本。 Gcc 曾经有两阶段查找的问题,但现在没有了。
【讨论】:
【参考方案2】:代码 sn-p,用 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> ;
【讨论】:
以上是关于将源代码从 Visual C++ 移植到 GCC 都有哪些陷阱[关闭]的主要内容,如果未能解决你的问题,请参考以下文章
C++ - 将 C++ 代码从 Visual Studio 移植到 Linux Eclipse IDE 时出现问题