sizeof运算符的实现

Rag*_*ddy 23 c linux gcc sizeof typecast-operator

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

#define my_sizeof(x) ((&x + 1) - &x)
Run Code Online (Sandbox Code Playgroud)

但它总是最终为任何一种数据类型提供结果为'1'.

然后我用谷歌搜索了它...我发现代码被类型化了

#define my_size(x) ((char *)(&x + 1) - (char *)&x)
Run Code Online (Sandbox Code Playgroud)

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

它也在努力

#define my_sizeof(x) (unsigned int)(&x + 1) - (unsigned int)(&x)
Run Code Online (Sandbox Code Playgroud)

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

提前致谢..

NPE*_*NPE 29

指针减法的结果是元素而不是字节.因此,第一个表达式1按定义进行求值.

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

#define my_sizeof(x) ((&x + 1) - &x)
#define my_sizeof(x) ((char *)(&x + 1) - (char *)&x)
Run Code Online (Sandbox Code Playgroud)

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

  • 作为替换`sizeof`的手段,这些宏是没有希望的.他们评估论证(两次)...想想`my_sizeof(x ++)`. (14认同)

Bas*_*tch 8

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

你应该理解C 指针算术.参见例如这个问题.指针差异以元素而非字节表示.


小智 7

#define my_sizeof(x) ((char *)(&x + 1) - (char *)&x)
Run Code Online (Sandbox Code Playgroud)

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

  1. sizeof 1- 4字节(对于具有4字节的平台int)
    my_sizeof(1)- 根本不会编译.

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

它只适用于变量.它不会对数据类型,如工作int,float,char像等,对于文字2,3.4,'A',等,也不是右值表达式像a+bfoo().

  • 这将是一个很好的评论,因为它没有回答所提出的问题,但它是["指导作者改进帖子的建设性批评"](http://stackoverflow.com/help/privileges/comment). .. (2认同)

roo*_*ler 6

#define my_sizeof(x) ((&x + 1) - &x)
Run Code Online (Sandbox Code Playgroud)

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

差异给出了这样的结果:x在该数量的内存中可以存储多少类型的变量,对于类型x来说显然是1(对于将其递增1并且取得差异就是我们已经完成的).

#define my_size(x) ((char *)(&x + 1) - (char *)&x)
Run Code Online (Sandbox Code Playgroud)

对它进行类型转换char*并获取差异将告诉我们char在给定的内存空间中可以存储多少个类型的变量(差异).由于每个char只需要1的存储器字节因此(存储器量)/ 1会给传递给宏,因此该类型的变量的存储器的量的变量的类型的两个连续的存储器位置之间的字节数x需要.

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


Oli*_*rth 5

但它最终总是将结果作为"1"表示任何一种数据类型

是的,这就是指针算术的工作原理.它以指向的类型为单位工作.所以铸造到char *工作单位char,这是你想要的.