C++ 不理解编译器的行为

C++ 不理解编译器的行为,c++,pointers,gcc,C++,Pointers,Gcc,我想了解为什么下面的代码实际工作,而不是给出一个seg错误。我让一位同事给我看了这个,我很惊讶 有人能给我解释一下,并给我指出一些好的链接来帮助我理解这一点吗 struct Test { int __in; int __in1; }; int main() { struct Test* t = NULL; int i = &(t->__in1) + 4; std::cout << i << std::endl; }

我想了解为什么下面的代码实际工作,而不是给出一个seg错误。我让一位同事给我看了这个,我很惊讶

有人能给我解释一下,并给我指出一些好的链接来帮助我理解这一点吗

struct Test {
    int __in;
    int __in1;
};

int main()
{
    struct Test* t = NULL;
    int i = &(t->__in1) + 4;
    std::cout << i << std::endl;
}

arun@arun-desktop:~/Code$ g++ -fpermissive -g test8.cc 
test8.cc: In function ‘int main()’:
test8.cc:11:24: warning: invalid conversion from ‘int*’ to ‘int’ [-fpermissive]
arun@arun-desktop:~/Code$ ./a.out   
20
arun@arun-desktop:~/Code$ 
struct测试{
int u; in;
int u_in1;
};
int main()
{
结构测试*t=NULL;
int i=&(t->u in1)+4;

std::cout如果试图访问无效内存,则只会出现分段错误。代码只执行指针算术,将指针调整为
Test
,以获取指向其成员之一的指针,而不会读取或写入指针的目标

这仍然是未定义的行为。孩子们,不要在家里这样做

(另外,不要在1
中使用like
\uu。也不要使用
-fppermissive
来允许这样的无意义转换:类型系统会帮助您。)

我稍微修改了您的代码,部分是为了帮助您解决警告/错误。在第一种情况下,您的指针后面没有内存,因此它没有元素。您已将其指向NULL。您需要将其指向NULL以外的对象(因此数学为NULL或零加上偏移量4加4),但这无法解决问题

在第二种情况下,它后面有一些内存,堆栈上的编译器分配了一个实际的结构

00000000 <fun>:
   0:   e3a00008    mov r0, #8
   4:   e12fff1e    bx  lr

00000008 <fun2>:
   8:   e24dd008    sub sp, sp, #8
   c:   e28d0008    add r0, sp, #8
  10:   e28dd008    add sp, sp, #8
  14:   e12fff1e    bx  lr
00000000:
0:e3a00008 mov r0,#8
4:E12FF1E bx lr
00000008 :
8:e24dd008子sp,sp,#8
c:e28d0008添加r0,sp,#8
10:e28dd008添加sp,sp,#8
14:E12FF1E bx lr
因此,有一点希望这样的代码能给你一个你可以使用的地址

当您使用适当的类型转换和命令行选项构建程序以克服错误时,它也将输出8

我看不出这样做地址数学有什么错,不是针对这个结构,但我可以看到这样的一些用例。你应该能够得到一个结构中一个项目的地址,你应该能够用这个地址做地址数学,这种数学没有什么不合法的

举个例子(只需在谷歌上搜索一下,找到另一个stackoverflow问题):

//g++-std=c++11 ptr.c-o ptr
#包括
#包括
结构测试{
int u; in;
int u_in1;
};
int main()
{
结构测试t;
intptr____________________;i=(intptr_________________________;
标准::cout
00000000 <fun>:
   0:   e3a00008    mov r0, #8
   4:   e12fff1e    bx  lr

00000008 <fun2>:
   8:   e24dd008    sub sp, sp, #8
   c:   e28d0008    add r0, sp, #8
  10:   e28dd008    add sp, sp, #8
  14:   e12fff1e    bx  lr
//g++ -std=c++11 ptr.c -o ptr
#include <iostream>
#include <cstdint>
struct Test {
    int __in;
    int __in1;
};

int main()
{
    struct Test t;
    intptr_t i = (intptr_t)(&(t.__in1))-(intptr_t)(&t) + 4;
    std::cout << i << std::endl;
}