MSVC支持但Clang报错的C语言行为解析
MSVC的非标
目的
因为在使用clang进行ast分析msvc项目的时候,出现了爆红现象,了解到msvc会有一些不严格按照c++标准但是允许的语法,在这点上clang就很严格,所以本文以clang为基准,记录到目前为止发现的msvc的非标语法。
友元别名
class A{};
class B
{
using AOtherName = A;
friend class AOtherName; // msvc允许,clang报错【别名不能和class/struct一起用】
friend AOtherName; // 正确做法
};
因为在 C++ 中,类型别名(通过 typedef 或 using 定义)不能与 class 或 struct 等修饰符一起使用。stack对此的回答
模板类显式特例化的命名空间限制
template<typename T>
struct AStruct
{
static bool isZero(const T& val);
};
namespace A
{
// msvc不报错,clang报错【模板特例化必须跟原始模板在同一命名空间】
template<>
struct AStruct<int>
{
static bool isZeros(const int& val)
{
return val == 0;
}
};
}
// 正确做法,同样定义在全局命名空间
template<>
struct AStruct<int>
{
static bool isZeros(const int& val)
{
return val == 0;
}
};
在C++中模板类的显式特化必须在其原始模板定义所在的命名空间中进行!stack对此的回答
但是在msvc编译器中,如果原始模板在全局命名空间中定义,msvc允许特例化在其他的命名空间,而结果等同于在全局命名空间中定义。
作者:foDol