本文参考出处:
什么是严格别名(堆叠)规定,以及为什么我们要关注它
C++标准中对表达式限定类型转换的描述(私翻)
(以下除了特殊标注部分,其余都是在C++中)
要直到什么是类型堆叠,首先要知道几个概念:
1:什么情况下两个类型是similar的
当两个类型中某一层有对应个数的p和完全相同的U,那么这两个类型就similar的,具体请参考上面的第二条参考.
2:动态类型
动态类型指的是在内存中的数据按照某个完整类型的分布,那么这个类型就是动态类型,通常存在于多态中,当一个泛左值表达式指代多态对象,则其最终派生对象的类型被称为动态类型
类型堆叠的概念:类型堆叠,实际上就是使用其他的类型通过对内存块再解析
但是这里标准明确规定:
除了以下类型的堆叠(别名)是合法的之外,其他的都是不合法的:
1,对象的动态类型
2,有cv访问限定的对象动态类型
3,和对象动态类型相似的类型
4,和对象动态类型相兼容的带signed或unsigned的类型
5,和带cv访问限定的对象动态类型兼容的带signed或unsigned的类型
6,包含了前5类类型的非静态数据成员(递归检查)的聚类(联合)
7,对象的动态类型的基类类型(可能有cv限定)
8,[signed]char,unsigned char或者std::byte类型
对以上内容的具体解释:(本文在github上同步的代码均在以下出现.)
#include <iostream>
#include <cstdlib>
struct foo{
int i = 1; //C++14起OK
};
int func(foo &s1,int *const s2){
s1.i = 1;
*s2 = 2;
return *s2;
}
struct foo1:foo{};
int func1(foo1 &s1,foo &s2){
s1.i = 1;
s2.i = 2;
return s1.i;
}
int main() {
int *point = (int *)std::malloc(sizeof(int)); //动态类型
(*point) = '0';
const int * cpoint = point;
std::cout<<*cpoint<<std::endl;
const int * const ccpoint = point;
std::cout<<*ccpoint<<std::endl;
unsigned int * upoint = (unsigned int *)point;
std::cout<<*upoint<<std::endl;
unsigned const int *ucpoint = (unsigned int *)point;
std::cout<<*ucpoint<<std::endl;
foo s;
std::cout<<func(s,&s.i)<<std::endl;
foo1 ss;
std::cout<<func1(ss,ss)<<std::endl;
std::cout<<*(char*)point<<std::endl;
return 0;
}