Welcome, Guest. Please login or register.

Author Topic: sizeof (*VarPtr) possible ?  (Read 5337 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: sizeof (*VarPtr) possible ?
« on: January 30, 2007, 08:00:27 PM »
Quote

Piru wrote:

Quote
No, I was expecting the compiler to assume (compile-time of course) that sizeof (*VarPtr) would be the same as sizeof (Var), simply because it's logic. This is assuming that Var is the variable VarPtr points to.

That is how it works.


sizeof() and offsetof() are usually implemented as macros on most implementations. That's the first indication that you can't absolutely rely on their behaviour in all cases.

Given that, I should point out that it can only work with concrete types that have already been "seen" by the compiler.

Consider this:

struct Something; /* forward reference */

sizeof(struct Something); /* we haven't seen it defined yet. How big is it? */

Furthermore, in C++ if you tried this:

Code: [Select]

class Base { ... };
class Derived : public Base { ... };

size_t getSize(const Base* b)
{
  /* return the size of the object pointed to */
  if (b) {
    return sizeof(*b);
  }
  throw std::invalid_argument();
}


the function would always return sizeof(Base) even when the object pointed to was of type "Derived". There is no way the compiler can know at compile time what the actual object pointed to really is at runtime.

int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: sizeof (*VarPtr) possible ?
« Reply #1 on: January 30, 2007, 09:26:15 PM »
I'm sure I'd once seen a definition of sizeof() somewhere :-)

Anyway, my point was that these constructs are not functions, there are no language guarentees for their behaviour if you treat them as if they were.

Quote
Actually you can rely on sizeof


How big is this?

struct AudioObject {
  unsigned long numSampleFrames;
  unsigned short sampleRate;

  ...

  signed short waveData[1]; /* memory beyond this point is wave data */
};

I've seen such "open ended" structures in a lot of places. Of course sizeof() cannot know you might have malloc()'ed this structure with an additional 200K worth of sample space.

And I've still seen people wonder why sizeof() didn't work for it, along with more comical examples, eg using sizeof() instead of strlen() for non-constant strings (and worse) :lol:

So, you can only rely on sizeof() when you fully understand its necessary limitations.

Quote
Well isn't that quite obvious, huh?


To you, yes. Never underestimate the ability of people to overlook the obvious however. I have seen code where I work that would give you hives.

Quote
C++ isn't C.


No, it's better in every significant way :-P

Seriously, that one word retort doesn't detract from the observation that sizeof() has no knowledge of the element actually pointed to. It simply trusts the developer to know what he has passed to it when dereferencing.

Consider the typical pointer casting frenzy that is the stock of amiga C coding. Often the pointer you deal with is not the genuine type of object pointed to, such as Task* v Process* . Getting the size of a Process by dereferencing a pointer that happens to be a Task* will return the size of the struct Task, not the struct Process.

You might sit there and complain this is totally obvious and I'd agree, but again people do make such silly assumptions, especually when they see such casts being used so loosely. You and I know that Process embeds a Task as its first member and therefore are not the same (or even comparable) structures, but it might not be as obvious to someone fairly new to the language.

In C++ the problem is compounded with abstract types as I describe and I have seen people who really ought to know a lot better attempt exactly what I demonstrated in that example.

So, obvious or not, such mistakes are made.
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: sizeof (*VarPtr) possible ?
« Reply #2 on: January 30, 2007, 09:50:01 PM »
As for sizeof() being unimplementable as a macro:

For physical instances of any given elemental type or structure (or instances accessed via dereferencing of a pointer to that type):

#define SIZEOF(t) ((long)((&(t))+1) - (long)(&(t)))

behaves about as well as sizeof(). Of course, it doesnt handle arrays properly or handle SIZEOF(TypeName) at all ;-)

int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: sizeof (*VarPtr) possible ?
« Reply #3 on: January 31, 2007, 12:59:43 AM »
Quote

Piru wrote:
@Karlos

Nor does it handle sizeof variable.


Of course not. The point was that it is possible to use a macro to evaluate the size of a structure/primitive type, nothing more. Just to demonstrate that (some of) the behaviour of sizeof() could be implemented as a macro, even if the actual sizeof() itself is not.

@Koafter

Agreed, it's disgusting and I'd want to shoot anybody I saw using anything quite like that*.

(*I have used some ugly macros in my time but only to abstract something that simply couldn't be represented more cleanly in the language itself. The above example naturally does not fall into this category).

C is a fantastic language but when you do end up having to depend on macros for things that you could readily do in C++ with inline functions and templates you really do see the point in moving up the language food chain ;-) Other than conditional compilation, I rarely use macros in C++ for anything.

I make no secret of the fact I regard C++ as utterly superior to C. Not because of the OO features per se (which I do like of course) but simply because it provides much cleaner ways of doing things that in C you would otherwise end up using the preprocessor or other contrivances for. It also provides greater error checking and general robustness and last but not least, still allows you to do things low level when you need to.
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: sizeof (*VarPtr) possible ?
« Reply #4 on: January 31, 2007, 01:24:16 AM »
Generally, I use the procedural paradigm where it makes sense and OO paradigm where it makes sense :-) I prefer the latter and for most systems I work on it's the right choice, but there are naturally lots of smaller things you have to do where it is just overkill.

C++ is so good simply because it gives you the choice. Unlike OO "pure" languages (read Java; forever lambasting C++ for its awkard syntax and then adopting the template syntax for its generics :lol:)) which force you to apply it to the simplest cases and of course procedural languages which make it awkward to do at all :-)
int p; // A