最近,我看到这样的说法:
所有指针具有相同的大小是很常见的,但从技术上讲,指针类型具有不同的大小是可能的。
但后来我发现了这样的内容:
虽然指针的大小都是相同的,因为它们只存储内存地址,但我们必须知道它们指向什么类型的东西。
现在,我不确定以上哪种说法是正确的。第二个引用的语句看起来像是来自佛罗里达州立大学计算机科学的 C++ 笔记。
这就是为什么在我看来所有指针都应该具有相同的大小:
1)假设我们有:
int i = 0;
void* ptr = &i;
Run Code Online (Sandbox Code Playgroud)
现在,假设 C++ 标准允许指针具有不同的大小。进一步假设在某些任意机器/编译器上(因为标准允许),a 的void*大小为 2 字节,而 a 的int*大小为 4 字节。
现在,我认为这里有一个问题,即右侧有一个int*大小为 4 字节的 ,而左侧有一个void*大小为 2 字节的 。int*因此,当从到发生隐式转换时,void*将会丢失一些信息。
2)所有指针都保存地址。由于对于给定的机器,所有地址都具有相同的大小,因此所有指针也应该具有相同的大小是非常自然(合乎逻辑的)。
因此,我认为第二句话是正确的。
我的第一个问题是 C++ 标准对此有何规定?
我的第二个问题是,如果 C++ 标准确实允许指针具有不同的大小,那么有理由吗?我的意思是允许指针具有不同的大小对我来说似乎有点不自然(考虑到我上面解释的两点)。所以,我很确定标准委员会一定已经考虑到了这一点(指针可以有不同的大小),并且已经有理由允许指针有不同的大小。请注意,只有当标准确实允许指针具有不同的大小时,我才会问这个(第二个问题)。
c++ pointers void-pointers language-lawyer pointer-conversion
我试图从成员函数做一些回调,一切都很好,直到我尝试使用从2个类派生的模板类作为回调对象时,我得到以下错误:
error C2440: 'reinterpret_cast' : Pointers to members have different representations; cannot cast between them
Run Code Online (Sandbox Code Playgroud)
这件事告诉我,成员函数指针有不同的表示形式(doh!)
这些陈述是什么?他们之间有什么区别?
以下代码是否在C++中定义良好?(*)
我很难弄清楚在标准中的哪个位置,并且搜索网络并没有发现具体的东西.
struct S;
struct T {
constexpr T() = default;
bool S::* a = nullptr;
int b = 42;
};
const T t{};
// Test. Compiled using: cl /W4 /WX /FAs filename.cpp
#include <stdlib.h>
int main() {
if (t.b != 42) abort();
}
Run Code Online (Sandbox Code Playgroud)
我问的原因是因为它适用于(或似乎)较新版本的GCC和Clang(x86/x86_64),但在Visual Studio 2015 Update 2和Update 3 RC中失败(**).
在报告错误之前,我想确定我不是依赖于未定义的行为,或者只是没有搜索正确的术语.
(*):我主要关心C++ 14及更高版本,但我认为答案不适用于C++ 11.
(**):如果代码定义明确,它看起来像一个codegen bug,它不是指针的分配空间.更改struct S到struct S{}似乎使代码的"工作".