首页 > 解决方案 > 为什么这个指针为空

问题描述

在 Visual Studio 中,指向成员变量的指针似乎是幕后的 32 位有符号整数(即使在 64 位模式下),并且在该上下文中空指针为 -1。因此,如果我有这样的课程:

#include <iostream>
#include <cstdint>

struct Foo
{
    char arr1[INT_MAX];
    char arr2[INT_MAX];
    char ch1;
    char ch2;
};


int main()
{
    auto p = &Foo::ch2;
    std::cout << (p?"Not null":"null") << '\n';
}

它编译并打印“null”。那么,我是在导致某种未定义的行为,还是编译器应该拒绝此代码而这是编译器中的错误?

编辑:

看来我可以保留“2 个INT_MAX数组加 2 个字符”模式,只有在这种情况下,编译器才允许我添加任意数量的成员,并且第二个字符始终被认为是 null。见演示。如果我稍微改变了模式(比如 1 或 3 个字符而不是 2 个),它会抱怨类太大。

标签: c++visual-studiolanguage-lawyer

解决方案


根据标准 [1] 的附件 B,对象的大小限制由实现定义。您的结构大小荒谬。

如果结构是:

struct Foo
{
    char arr1[INT_MAX];
    //char arr2[INT_MAX];
    char ch1;
    char ch2;
};

...在相对较新的 64 位 MSVC 版本中,结构的大小似乎约为 2147483649 字节。如果你再添加 arr2,突然 sizeof 会告诉你 Foo 的大小为 1。

C++ 标准(附件 B)规定编译器必须记录限制,MSVC 就是这样做的 [2]。它声明它遵循建议的限制。附件 B,第 2.17 节为对象的大小提供了 262144(?) 的建议限制。虽然很明显 MSVC 可以处理更多,但它记录了它遵循最低建议,所以我认为当你的对象大小超过这个值时你应该小心。

[1] http://eel.is/c++draft/implimits

[2] https://docs.microsoft.com/en-us/cpp/cpp/compiler-limits?view=vs-2019


推荐阅读