为什么这个指针为空

Ayx*_*xan 32 c++ visual-studio language-lawyer

在 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';
}
Run Code Online (Sandbox Code Playgroud)

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

编辑:

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

com*_*uip 8

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

如果结构是:

struct Foo
{
    char arr1[INT_MAX];
    //char arr2[INT_MAX];
    char ch1;
    char ch2;
};
Run Code Online (Sandbox Code Playgroud)

...在相对较新的 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


Bar*_*hou 0

当我测试代码时,VS 显示Foo: the class is too large. 在此输入图像描述

当我添加时char arr3[INT_MAX],Visual Studio 将报告Error C2089 'Foo': 'struct' too large。微软文档将其解释为The specified structure or union exceeds the 4GB limit. 在此输入图像描述

  • 这是因为该类经过精心编写,干净地包裹着指向 -1 的指针。当你改变东西时,这种情况就不会发生。 (3认同)