sizeof运算符的实现

问题描述 投票:23回答:8

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

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

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

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

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

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

它也在努力

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

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

提前致谢..

c linux gcc sizeof typecast-operator
8个回答
29
投票

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

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

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

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


8
投票

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

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


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) - 根本不会编译代码。

它只适用于变量。它不适用于像intfloatchar等数据类型,如23.4'A'等文字,也不适用于a+bfoo()等rvalue表达式。


6
投票
#define my_sizeof(x) ((&x + 1) - &x)

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

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

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

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

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


5
投票

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

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


0
投票

我昨天搜索了这个,我找到了这个宏:

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

它只扩展了一次X(没有错误作为像x ++这样的表达式的双重评估),并且它到目前为止工作正常。


-1
投票

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

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

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


-1
投票
#include<bits/stdc++.h>

using namespace std;
//#define mySizeOf(T) (char*)(&T + 1) - (char*)(&T)

        template<class T>
size_t mySizeOf(T)
{
        T temp1;
        return (char*)(&temp1 + 1) - (char*)(&temp1);
}
int main()
{
        int num = 5;
        long numl = 10;
        long long numll = 100;
        unsigned int num_un_sz = 500;

        cout<<"size of int="<<mySizeOf(num) << endl;
        cout<<"size of long="<<mySizeOf(numl) << endl;
        cout<<"size of long long ="<<mySizeOf(numll) << endl;
        cout<<"size of unsigned int="<<mySizeOf(num_un_sz) << endl;
        return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.