c++ - 为什么这个指针为空

标签 c++ visual-studio language-lawyer

在Visual Studio中,指向成员变量的指针似乎是幕后的32位带符号整数(即使在64位模式下),在这种情况下,空指针为-1。所以,如果我有一个像这样的类(class):

#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个字符”的模式,只有在这种情况下,编译器才允许我添加任意数量的成员,并且第二个字符始终被视为空。 See demo。如果我稍微改变了模式(在某些时候像1或3个字符而不是2个字符),它会提示该类太大。

最佳答案

根据标准[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

关于c++ - 为什么这个指针为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64143169/

相关文章:

c++ - 模板构造函数

c++ - 一个函数可以使用点运算符调用另一个函数吗

c++ - 通过 constexpr union 进行类型双关

c++ - 控制 USB 端口

c++ - 快速的每列求和。可能的?

.net - 如何在 Visual Studio 中从 .NET 项目引用 C++ 库项目?

c# - Visual Studio 停止运行我的程序

c - memcmp 应该返回什么?

c++ - 头文件和 odr 中的 constexpr 全局常量

c++ - 在 c++ 中,从 unsigned int 到 int 的转换总是保留位模式吗?