我们一般都知道sizeof(long) != sizeof(int)。但是(C++11)标准的哪些部分不允许通过int*对long*进行混叠?这仅仅是因为conv.ptr中的遗漏,basic.lval中的混叠规则,还是其他什么原因?
void f()
{
static_assert(sizeof(int) == sizeof(long), "");
long x[] = {1, 2};
int* y = x; // error: invalid conversion from ‘long int*’ to ‘int*’ [-fpermissive]
}发布于 2014-05-23 14:01:56
是的,这是[conv.ptr]中的遗漏,适用的段落在[expr.reinterpret.cast]中,
7对象指针可以显式转换为不同类型的对象指针。当“指向T1的指针”类型的are转换为“指针到cv T2”类型时,如果T1和T2都是标准布局类型(3.9),并且T2的对齐要求并不比T1严格,或者如果这两种类型都是无效的,则结果是static_cast<cv T2*>(static_cast<cv void*>(v))。将“指针到T1”类型的prvalue转换为“指向T2的指针”类型(其中T1和T2是对象类型,T2的对齐要求并不比T1更严格),并返回到原始类型产生原始指针值。任何其他此类指针转换的结果都是unspecified。
你必须使用reinterpret_cast<int*>(...)。
编辑.在我的评论中有一个问题,我在这个编辑中更加明显,这不是一个语言律师问题,而是意图使用指针。我不知道这种担忧是如何产生的,因为很明显,我们可以不问就简单地进行C转换,但是如果存在疑问,那么指向int*的指针转换就违反了strict aliasing规则。
也就是说,可能会出现未定义的行为,因为您打破了编译器的假设,即不同类型的指针永远不能指向相同的内存位置。
发布于 2014-05-23 14:26:20
long和int是两种不同的类型,即使它们大小相同,所以我认为无效的转换是由basic.lval.10造成的。
如果程序试图通过除下列类型之一以外的glvalue访问对象的存储值,则行为是未定义的:
另外,如果basic.lval不存在,还会有其他问题:相同的大小并不意味着相同的表示/范围。
不能保证int中的值位与long中的值位精确对应。
https://stackoverflow.com/questions/23829696
复制相似问题