sizeof运算符的实现

时间:2013-01-05 11:01:36

标签: c linux gcc sizeof typecast-operator

我尝试过实现sizeof运算符..我已经这样做了..

#define my_sizeof(x) ((&x + 1) - &x)

但它总是最终为数据类型中的任何一个提供结果为“1”。

然后我用谷歌搜索了它...我发现代码 typecasted

#define my_size(x) ((char *)(&x + 1) - (char *)&x)

代码工作如果它是typecasted ...我不明白为什么..这个代码也完美地填充结构..

它也适用于

#define my_sizeof(x) (unsigned int)(&x + 1) - (unsigned int)(&x)

任何人都可以解释一下,如果进行类型转换,如果不进行类型转换,它是如何工作的?

提前致谢..

9 个答案:

答案 0 :(得分:29)

指针减法的结果在元素中,而不是以字节为单位。因此,第一个表达式根据定义评估为1

除此之外,你真的应该在宏中使用括号:

#define my_sizeof(x) ((&x + 1) - &x)
#define my_sizeof(x) ((char *)(&x + 1) - (char *)&x)

否则,在表达式中尝试使用my_sizeof()可能会导致错误。

答案 1 :(得分:8)

sizeof运算符是C(和C ++)语言规范的一部分,并在编译器(前端)中实现。没有办法用其他C构造实现它(除非你使用像typeof这样的GCC扩展),因为它可以接受类型或表达式作为操作数,而不会产生任何副作用(例如sizeof((i>1)?i:(1/i)) won'在i==0时崩溃但你的宏my_sizeof会因为除零而崩溃)。另请参阅C coding guidelineswikipedia

你应该了解C pointer arithmetic。参见例如this question。指针差异用元素表示,而不是字节。

答案 2 :(得分:7)

#define my_sizeof(x) ((char *)(&x + 1) - (char *)&x)

my_sizeof()宏在以下情况下不起作用:

  1. sizeof 1 - 4个字节(对于4字节int的平台)
        my_sizeof(1) - 根本没有编译。

  2. sizeof (int) - 4个字节(对于4字节int的平台)
        my_sizeof(int) - 根本不会编译代码。

  3. 它仅适用于变量。它不适用于intfloatchar等数据类型,适用于23.4,{{1}等文字}等等,也不是像'A'a+b这样的右值表达式。

答案 3 :(得分:6)

#define my_sizeof(x) ((&x + 1) - &x)

&x给出在程序中声明的变量的地址(比如说是双x),并用1递增它给出了可以存储x类型的下一个变量的地址(这里addr_of(x) + 8 ,对于double的大小是8Byte)。

差异给出了这样的结果:x类型的变量可以存储在该数量的内存中,对于x类型显然是1(对于将其递增1并且取差异就是我们& #39;已完成)。

#define my_size(x) ((char *)(&x + 1) - (char *)&x)

将其类型转换为char*并获取差异将告诉我们有多少类型char的变量可以存储在给定的内存空间中(差异)。由于每个char只需要1字节的内存因此(内存量)/ 1将给出传递给宏的变量类型的两个连续内存位置之间的字节数,从而得到内存量。 x类型的变量需要。

但是你无法将任何文字传递给这个宏并知道它们的大小。

答案 4 :(得分:5)

  

但它总是最终为数据类型

提供结果为'1'

是的,这就是指针算术的工作原理。它以指向的类型为单位工作。因此,转换为char *工作单元char,这就是你想要的。

答案 5 :(得分:1)

这对文字和变量都适用。

Splint 3.1.1 --- 12 April 2003

Maintainer: splint-bug@splint.org
Compiled using Microsoft Visual C++ 6.0

答案 6 :(得分:0)

我昨天进行了搜索,发现了这个宏:

#define mysizeof(X)  ((X*)0+1)

仅将X扩展一次(对于x ++这样的表达式的双重求值,不会出错),并且到现在为止都可以正常工作。

答案 7 :(得分:-1)

#define my_sizeof(x)((& x + 1) - & x)

& x给出变量的地址,并用一个(& x + 1)递增它,将给出地址,其中可以存储另一个x类型的变量。 现在,如果我们对这些地址进行算术运算,如((& x + 1) - & x),那么它将告诉在((& x + 1) - & x)地址范围1 x类型的变量可以存储。

现在,如果我们使用(char *)对内存量进行类型转换[因为char的大小是1个字节并且递增char *只会移动一个字节],那么我们将得到x类型消耗的字节数

答案 8 :(得分:-1)

LoaderManager.getInstance(this).initLoader(0,null,mRecipeLoaderManager);