sizeof如何工作?我怎么写自己的?

dat*_*ili 11 c++

我知道C++并且知道函数sizeof本身,但我需要编写自己的sizeof函数,所以请解释它是如何工作的?它对参数有什么作用?

Tyl*_*nry 31

sizeof是一个编译器内置运算符.它在编译时由编译器进行评估,并且后面没有运行时代码.你不能自己写.

询问这类似于询问如何编写自己的版本return.

  • 是否有可能编写自己的`return`版本? (3认同)

AnT*_*AnT 28

您没有提供有关您想要做什么的任何有意义的详细信息,因此很难弄清楚您需要什么.

您可以sizeof通过自己的模板功能"包装"

template <typename T> size_t my_sizeof() {
  return sizeof(T);
}
Run Code Online (Sandbox Code Playgroud)

然后用它作为

size_t s = my_sizeof<int>();
Run Code Online (Sandbox Code Playgroud)

有时可以遇到使用而实现类似sizeof功能的请求sizeof.这样的要求没有任何实际意义,但有时被用作家庭作业.人们可以这样做如下

template <typename T> size_t my_sizeof() {
  T t;
  return (char *) (&t + 1) - (char *) &t;
}
Run Code Online (Sandbox Code Playgroud)

这将需要默认可构造T.一个限制较少但正式非法的解决方案(黑客)就像是

template <typename T> size_t my_sizeof() {
  return (char *) ((T *) NULL + 1) - (char *) (T *) NULL;
}
Run Code Online (Sandbox Code Playgroud)

以上实现实现了基于类型的sizeof.

尝试模拟基于值的功能sizeof可能如下所示

template <typename T> size_t my_sizeof(const T& obj) { 
  return my_sizeof<T>();
}
Run Code Online (Sandbox Code Playgroud)

但是sizeof至少因为内置sizeof函数没有评估它的参数,这甚至不会远远等同于内置函数.

最后,这些实现都不会像内置sizeof函数那样产生整数常量表达式(ICE).在当前版本的语言中无法实现以这种方式生成ICE.

无论如何,这一切当然完全没有任何实际价值.只需sizeof在想知道尺寸时使用.

  • @kbok:不正确.在C语言中`sizeof(char)`总是正好1.它是*由C定义的常量.如果在某些系统`char`占用超过1个机器字节,那只表示从C语言的角度来看每个C -byte将包含几个机器字节.`sizeof(char)`仍然是1.换句话说,C中的`sizeof`计算为`char`s中的对象/类型大小,所以无论什么`sizeof(char)`总是1. (3认同)
  • +1,@ AndreyT.在C和C++中,`char`总是1个字节.这并不意味着它是8位,但它*总是1个字节,因此`sizeof(char)== 1`总是如此. (2认同)

Bil*_*ill 7

编写自己的sizeof()函数的一种不可移植的方法是利用基于堆栈的变量通常如何在内存中布局:

#include <iostream>
using namespace std;

template <typename T>
int mysizeof(T)
{
  T temp1;
  T temp2;

  return (int)&temp1 - (int)&temp2;
}

int main()
{
  cout << "sizeof mysizeof" << endl;

  char c = 0; short s = 0; int i = 0; long l = 0;
  float f = 0; double d = 0; long double ld = 0;

  cout << "char: " << mysizeof(c) << endl;
  cout << "short: " << mysizeof(s) << endl;
  cout << "int: " << mysizeof(i) << endl;
  cout << "long: " << mysizeof(l) << endl;
  cout << "float: " << mysizeof(f) << endl;
  cout << "double: " << mysizeof(d) << endl;
  cout << "long double: " << mysizeof(ld) << endl;
}
Run Code Online (Sandbox Code Playgroud)

看到它在行动.
0参数版本.
使用一个数组而不是两个变量的版本.

警告:这是一个有趣的谜题,但你不应该在实际代码中使用它. sizeof保证工作.这不是.仅仅因为它适用于此平台的此版本编译器并不意味着它适用于任何其他版本.

真正的运算符利用成为编译器的一部分.Sizeof知道每种类型的变量有多大,因为它必须知道.如果编译器不知道每种类型有多大,它将无法将程序放在内存中.

编辑:请注意,所有这些有缺陷的示例都依赖于原始sizeof运算符.它用于分隔堆栈变量,以及创建和索引数组变量.

  • 拥有两个项目的数组可能更安全,而不是指望编译器将locals放入给定的顺序.array [1]总是在array [0]之后,并且有正确的填充. (4认同)