关于C/C++获取指针大小判断系统位数的猜想

30 篇文章 2 订阅
22 篇文章 0 订阅

不讨论使用sizeof


第一个程序,指针类型会根据系统位数的大小而分配。

#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出了问题,关于什么问题,目前也不清楚了,知道的同学指教一下~~~~







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值