开发者

How does sizeof work? How can I write my own?

I know C++ and know the function sizeof itself but I need to write my own s开发者_JAVA技巧izeof function so please explain how it works exactly? What does it do with the parameter?


sizeof is a compiler built-in operator. It is evaluated at compile-time by the compiler, and there is no runtime code behind it. You cannot write your own.

Asking this is akin to asking how you would write your own version of return.


You haven't provided any meaningful details about what it is you want to do, so it is hard to figure out what you need.

You can "wrap" sizeof by you own template function like

template <typename T> size_t my_sizeof() {
  return sizeof(T);
}

and then use it as

size_t s = my_sizeof<int>();

From time to time one can come across a request to implement sizeof-like functionality without using sizeof. Requests like that make no practical sense whatsoever, yet sometimes are used as homework assignments. One can probably do it as follows

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

which would require a default-constructible T. A less restricting but formally illegal solution (a hack) would be something like

template <typename T> size_t my_sizeof() {
  return (char *) ((T *) NULL + 1) - (char *) (T *) NULL;
}

The above implementations implement type-based sizeof.

An attempt to emulate the functionality of value-based sizeof might look as follows

template <typename T> size_t my_sizeof(const T& obj) { 
  return my_sizeof<T>();
}

but this will not be even remotely equivalent to the built-in sizeof, at least because the built-in sizeof does not evaluate its argument.

Finally, neither of these implementations will produce integral constant expressions (ICE), as the built-in sizeof does. Producing an ICE that way is impossible to achieve in the current version of the language.

In any case this all, of course, is totally devoid of any practical value. Just use sizeof when you want to know the size.


A non-portable way to write your own sizeof() function is to take advantage of how stack-based variables are often laid out in memory:

#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;
}

See it in action.
A 0-parameter version.
A version that uses one array instead of two variables.

Warning: This was a fun puzzle, but you should never use this in real code. sizeof is guaranteed to work. This is not. Just because it works on this version of this compiler for this platform does not mean it will work for any other.

The real operator takes advantage of being a part of the compiler. Sizeof knows how big each type of variable is because it has to know. If the compiler doesn't know how big each type is, it wouldn't be able to lay your program out in memory.

Edit: Note that all of these flawed examples rely on the original sizeof operator. It's used to space the stack variables, and to create and index array variables.


As already said it is an operator not a function, but additionally it is one of the operators for which operator overloading is not allowed:

Bjarne Stroustrup's C++ Style and Technique FAQ: Why can't I overload dot, ::, sizeof, etc.?

I can think of no conceivable reason why you would want to overload this in any case. If you have an class for which size information other than that which sizeof yields is required, then simply add a member function to provide that information; as for example in std::string:size() which returns the length of the string managed by the object rather than the size of the object which is semantically different; you do not want to monkey with the semantics of sizeof!


sizeof is an C++ operator which yields the number of bytes in the object representation of its operand. Result of sizeof is an implementation-defined constant of type size_t, but should meet the requirements set forth in C++ Standard 5.3.3. You could write your own type traits that will work similar to built-in sizeof operator.

template<typename T> struct get_sizeof;

template<> struct get_sizeof<char>          { static const size_t value = 1; };
template<> struct get_sizeof<unsigned char> { static const size_t value = 1; };
template<> struct get_sizeof<int>           { static const size_t value = 4; };
template<> struct get_sizeof<long>          { static const size_t value = 4; };
// etc.

...
// sample of use
static const size_t size = get_sizeof<int>::value;
char x[get_sizeof<int>::value];

But this have no sense since only creators of the compiler are knows actual values of value for the implementation.


sizeof isn't a function, and you can't write your own version. The compiler works out the type of the argument (unless it's already a type), then substitutes the expression with an integer constant.


I saw this post when searching for a way to get the same functionality as the sizeof operator. It turned out that I implemented a function called bit_sizeof() that looks a lot like the operator sizeof, but which returns the number of bits of a given type instead. I implemented a global template function like this:

#include <limits.h>   //For CHAR_BIT

//Global function bit_sizeof()
template<typename TSizeOfType>
constexpr uint32_t bit_sizeof(TSizeOfType)
{
   return (sizeof(TSizeOfType) * CHAR_BIT);
}

This function requires the use of the c++11 standard, as it uses the keyword constexpr. Without the keyword constexpr, the function will compile still. But the compiler may not optimize properly and put in a function call at each call site of using the bit_sizeof function. With the use of constexpr, the whole function evaluates to a constant, which in my knowledge should be exactly equivalent to how the sizeof operator works? Correct me if I am wrong. In use I call the function like this, with an added parantesis after the type:

uint32_t uiBitsInType = bit_sizeof(char());

The function can be useful when creating bit masks for example:

uint32_t uiMask = (((uint32_t(0x1) << bit_sizeof(char())) - 0x1) << bit_sizeof(char()));

Which could be more readable than this:

uint32_t uiMask2 = (((uint32_t(0x1) << (sizeof(char) * 0x8)) - 0x1) << (sizeof(char) * 0x8));

Personally I have other uses for this function also.


If he wants to write his own sizeof he just needs to grab the source code of a C++ compiler and go ahead. The source will also show how sizeof can be implemented.


sizeof is evaluated at compile-time (Boost and Loki make use of it). So, I think, it is impossible to write sizeof - complain function for dynamically allocated buffer.


sizeof isn't a function. It's an operator in C. We can implement its functionality something like follows.

#include <stdio.h>

#define mysizeof(X)  \

           ({                    \
                  __typeof(X) x;  \
                  (char *) (&x+1) - (char*) (&x); \
           })
int main()
{

     struct sample
     {
         int a;float b; char c;
     };

     printf("%d", mysizeof(struct sample));
     return 0;
}

Answer : 12

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜