C++ 不理解编译器的行为
我想了解为什么下面的代码实际工作,而不是给出一个seg错误。我让一位同事给我看了这个,我很惊讶 有人能给我解释一下,并给我指出一些好的链接来帮助我理解这一点吗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; }
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;
}