原文:http://blogs.msdn.com/xiangfan/archive/2008/08/29/online-c-compilation-service.aspx
网上有许多在线C++编译器。你可以利用它们对你的代码针对各种C++编译器进行兼容性测试,而不需要购买和安装这些编译器。
下面的网址是最有名的两个在线C++编译网站:
许多在线判题系统也可以用来进行在线编译:
你可能会好奇这些网站使用的编译器的版本和编译参数到底是什么。有些网站会提供这些信息,而有些则不会。那么你就只能靠自己去发现这些“秘密”了。
工欲善其事,必先利其器。让我们先看看一些从编译器获取信息的小技巧。
1. 输出宏
在C++中, 字符串常数不能作为模板参数。大多数编译器会在错误信息中同时输出字符串的内容。下面的代码展示了这一技巧。
template<const char *> class A {};
#define F0(x) #x
#define F1(x) F0(x)
#define V1 F1(__GNUC__)
int main()
{
A<V1> a1;
}
这里,宏F0和F1用于将整型转换成字符串。编译器会输出类似于"literal "3" is not a valid template argument because it is the address of an object with static linkage"的出错信息。里面的"3"就是你想知道的宏的内容。
2. 输出常数
同样,浮点数是不能作为模板参数的。编译器通常会在错误信息中包含浮点数的值。利用这一点,我们可以输出浮点常数。不过很不幸的是,VC会隐式的将浮点类型的模板参数转换成int(参见https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=296008)
下面是一种输出整型常量的方法:
template<int N>
class A
{
private:
A();
};
int main()
{
A<sizeof(char)> a;
}
3. 输出变量类型
有时候,你可能需要知道某些变量的实际类型,这时候你可以使用下面的代码:
struct Dummy {};
void Fun(const Dummy &);
int main()
{
Fun(1+1U);
}
PS:如果你使用的是gcc,那么它会输出"not convert `2' to `const Dummy&'",所以你需要将Fun的声明改成"template<typename T> void Fun(T);"(换句话说,在gcc中上面的代码也可以用于输出常数的值)
4. 输出包含路径
如果要获取STL头文件的路径,你可以使用:
#include <ext/hash_set>
using __gnu_cxx::hash_set;
int main()
{
hash_set<> m;
}
PS:这里也可以使用vector。
好,现在是时候牛刀小试了。关于如何获取编译器的版本信息,可以参考这篇文章:Pre-defined Compiler Macros
下面是利用上面介绍的技巧获得的dinkumware网站的一些资料:
1. VC
版本 (_MSC_FULL_VER):
VC8 140050727
VC7.1 13103077
VC7 13009466
VC6 12008804
包含路径:
D:/cplt501_vc_source/include (with _CPPLIB_VER=501)
2. EDG
版本(__EDG_VERSION__):
3.05
编译参数:
edgcc --alt -D_WIN32 -D_M_IX86 --no_inlining --diag_suppress=1290 --long_long --wchar_t_keyword -D_C99 -ID:/cplt501_gen_source/include/c -ID:/cplt501_gen_source/include -IC:/PROGRA~1/MICROS~2.NET/VC7/include --exceptions --microsoft -c sourceFile.cpp
因为使用了VC兼容模式进行编译,所以编译器可能会模拟VC的部分bug
3. GCC
版本:
3.2.0
包含路径:
D:/cplt501_gen_source/include and D:/Mingw/include/c++/3.2/
可以看到这里使用的GCC的版本已经相当陈旧了