2

I understand the reason behind why sizeof is not implemented as function from Why is sizeof considered as an operator?

But i do not get is why we need to implement sizeof as special type of unary operator which execute as compile time not runtime (i guess As other operators always executed as runtime)

Same things we can achieve by making sizeof as macro isnt it?. What is the difference between such compiled time unary operator and macros?


i just want to know why they did not think for macro first and rather then implementing different operator. When i first thought what is sizeof() i thought it should be macro. didnt think of such unary operator ever.

Community
  • 1
  • 1
Jeegar Patel
  • 26,264
  • 51
  • 149
  • 222
  • Did you google it! Whats the difference between `compile time unary operator and macros`? – Sathish Aug 14 '14 at 06:30
  • 4
    "same things we can achieve by making sizeof as macro" - **no, you can't.** Also, C99 supports VLAs, and the `sizeof` a VLA is evaluated at runtime. – The Paramagnetic Croissant Aug 14 '14 at 06:35
  • 4
    As a general rule, if something can be evaluated at compile time, it should be. One wants the compiler to do as much work as possible and so reduce the runtime burden. – David Heffernan Aug 14 '14 at 06:36
  • Your code and libraries would be bloated with type information so that `sizeof(some_data)` or `sizeof(*some_ptr)` could be evaluated at runtime. – indiv Aug 14 '14 at 06:38
  • 1
    "other operators always executed as runtime"? Really? That's simply not true. Constant expressions like `2 + 3 * 8` are required to be evaluated at compile time. – AnT stands with Russia Aug 14 '14 at 06:41
  • @Mr.32: So, how do you propose to implement `sizeof` as a macro? – AnT stands with Russia Aug 14 '14 at 06:41
  • @AndreyT i just want to know why they did not think for macro first and rather then implementing different operator. When i first thought what is sizeof() i thought it should be macro. didnt think of such unary operator ever. – Jeegar Patel Aug 14 '14 at 06:44
  • 2
    @Mr.32 Why are you stubbornly sticking to your idea that it **should** be a macro? Why **should** it be? It **should not,** in fact. First of all, macros are inferior to operators in many way. They are not type-safe (in fact, they are not safe at all), they are confusing, they can cause clutter. Second, the size of a data type is an intrinsic concept in a programming language, tightly coupled with its semantics. So, the preprocessor, which is just a syntactic, text-only tool, cannot, need not, and should not know anything about object sizes. – The Paramagnetic Croissant Aug 14 '14 at 09:19

3 Answers3

6

Your question is not without merit. In fact, standard library already has a very similar feature implemented as a macro: it is the standard offsetof macro. Note also that a large portion of sizeof's usability comes form its compile-time nature (also true for offsetof), which is why a run-time implementation would be significantly inferior. (And, BTW, your assertive statement claiming that all other operators are "always executed at runtime" is completely untrue.)

One reason sizeof could not be implemented as a macro even in the original C language was the fact that it was supposed to accept both types and expressions as arguments. It would be impossible to cover both kinds of arguments with a single macro. We'd need at least two macros: one for types and one for expressions. But even if we agree to separate these two forms of sizeof into two different macros, it still would be rather difficult (or even impossible) to implement a macro that would handle expression arguments properly.

Meanwhile, if we restrict ourselves to the original C (i.e. exclude from consideration C99 VLAs), then we could probably implement sizeof for type arguments as a macro

#define sizeof(T) ((size_t) ((T *) 0 + 1))

This is pretty much the same technique that is used to implement the standard offsetof as a macro.

The above macro implementation is still not perfect, since it will not work properly for, say, int[6] argument, but you get the idea. This, BTW, might be another point in favor of a built-in operator implementation instead of a macro.

But how to do the same thing for expression arguments - I don't know. Do you?

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
3

Macros are processed by the preprocessor. Operators are processed by the compiler.

Although sizeof(int) can be easily determined by the preprocessor, think about sizeof(MyCustomStruct). In order to evaluate it, we must know the structure of MyCustomStruct, which is only evaluated by the compiler.

The advantage of compile time over run time is of course performance. If you can do it once in compile time, why doing it many times in run time?

Tzach
  • 12,889
  • 11
  • 68
  • 115
  • Well, that is not entirely accurate. Actually, standard library has such macro as `offsetof`. The functionality of that macro is not that much different from `sizeof` for type arguments. And `offsetof` is often implemented as a genuine macro (there are quite a few topics on that). And, just like `sizeof`, it generates a compile time constant. At least part of the functionality of `sizeof` can be implemented in exactly the same way (see my answer). – AnT stands with Russia Aug 14 '14 at 07:06
1

other operators always executed as runtime.

That is not true; operators in constant expressions are evaluated at compile time. So for example, 15 * 60 is compile time evaluated. The sizeof operator expressions, other than VLAs introduced in C99, are are by definition constant, so are always evaluated at compile time.

Clifford
  • 88,407
  • 13
  • 85
  • 165