关于C/C++获取指针大小判断系统位数的猜想
2016-03-16 10:28
537 查看
不讨论使用sizeof
第一个程序,指针类型会根据系统位数的大小而分配。
但是这里存在一个问题,将p转换成long,如果在32位的编译期的话,那么long就是32,那么这个结果就是32,不正确,存在精度的损失。
第二个程序,利用结构体,通过计算成员的偏移位置offset确定指针大小。
但其实指针大小跟编译器是有相关,编译器可根据编译选项编译出不同大小的指针,或32或64位。
建议可以深入学习一下《深入理解c指针》,关于用size_t 和 intptr_t的一些判断方法。
另外,linux下的getconf LONG_BIT可以获取系统位数~~~~~~~~~
==================================华丽的分割线========================================
下面是C++ class一些data member layout的讨论,和程序二类似。
g++编译输出:
![](http://img.blog.csdn.net/20160316101436569?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
①这里用printf输出,对于cout输出type class::*类型指针应是不合法的,可参见《深入探索C++对象模型》p131.
②这里输出了1,而且两个data member都输出了1,估计cout见到指针都慌了!!
③data member layout:
上面程序有个问题就是,printf输出了8,见下面一段程序:
如果不在data member offset上加上1,那么无法判断指针到底有没有指向data member了,所以在class data member上加1来判断。
但是一些编译器,比如microsoft visual c++ 或许会输出0,因为它内部有一些手脚~~~~
上面cout两个data member 都是1,是cout出了问题,关于什么问题,目前也不清楚了,知道的同学指教一下~~~~
第一个程序,指针类型会根据系统位数的大小而分配。
#include <stdio.h> int main(int argc, char *argv[]) { int *p = (int *)~0; int count = 0; for (;p!=0;) { p = (int *)((long)p << 1); count++; } printf("%d\n",count); return 0; }
但是这里存在一个问题,将p转换成long,如果在32位的编译期的话,那么long就是32,那么这个结果就是32,不正确,存在精度的损失。
第二个程序,利用结构体,通过计算成员的偏移位置offset确定指针大小。
#include <stdio.h> #define bit(type, mem) ((int)&((type *)0)->mem) struct A { int *p; int a; }; int main(int argc, char *argv[]) { printf("%d\n", bit(struct A,a)*8); return 0; }上面,define计算出了偏移位置,如果指针大小和编译器无关,那么结果是真确的。
但其实指针大小跟编译器是有相关,编译器可根据编译选项编译出不同大小的指针,或32或64位。
建议可以深入学习一下《深入理解c指针》,关于用size_t 和 intptr_t的一些判断方法。
另外,linux下的getconf LONG_BIT可以获取系统位数~~~~~~~~~
==================================华丽的分割线========================================
下面是C++ class一些data member layout的讨论,和程序二类似。
#include <iostream> #include <stdio.h> using namespace std; #define bit_cpp(type, mem) (&type::mem) class B { public: int *p; int b; }; int main(int argc, char *argv[]) { // FIrst printf("%p\n", bit_cpp(B, b)); // Second cout << &B::p << endl << &B::b << endl; return 0; }
g++编译输出:
①这里用printf输出,对于cout输出type class::*类型指针应是不合法的,可参见《深入探索C++对象模型》p131.
②这里输出了1,而且两个data member都输出了1,估计cout见到指针都慌了!!
③data member layout:
上面程序有个问题就是,printf输出了8,见下面一段程序:
int B::**pp = 0; int B::**pp1 = &B::p; if (pp1 == pp) { // do something. }
如果不在data member offset上加上1,那么无法判断指针到底有没有指向data member了,所以在class data member上加1来判断。
但是一些编译器,比如microsoft visual c++ 或许会输出0,因为它内部有一些手脚~~~~
上面cout两个data member 都是1,是cout出了问题,关于什么问题,目前也不清楚了,知道的同学指教一下~~~~
相关文章推荐
- 四道经典C语言指针试题
- c++二叉树的建立、前序中序后序深搜、宽搜、宽搜带行号
- c++中endl与“\n”的区别
- C++继承方式
- C++多态的实现及原理详细解析
- 重温C语言之--文件操作
- C++ 溢出与越界
- c实现各种进制间转换
- C语言+嵌入式SQL+DB2开发经验总结
- C++设计模式——单例模式 系列
- CCameraConfig.cpp文件中define替换
- C++ char*,const char*,string的相互转换
- C++实现解析INI配置文件
- C++静态成员函数&静态数据成员
- LeetCode: 2. Add Two Numbers 【C 解题】
- C++ 标准库 vector list map使用方法
- c读写常见错误
- c++实现split函数
- C语言构建WEB管理系统(五):CGI实现上传文件
- C语言构建WEB管理系统(四):CGI程序解析POST数据