Re: replacement for sizeof()

Discussion in 'C Programming' started by Atreya, Chaitanya, Aug 10, 2003.

  1. #define SIZE(x) ((unsigned int)((char *)(&x + 1) - (char *)&x))

    vishnu mahendra wrote:
    > can anyone please tell me how to find the size of a variable or a
    > datatype with out using a sizeof() operatot.
    > thank you in advance,
    > vishnu
    Atreya, Chaitanya, Aug 10, 2003
    #1
    1. Advertising

  2. Atreya, Chaitanya

    Mark Guest

    Atreya, Chaitanya wrote:
    > #define SIZE(x) ((unsigned int)((char *)(&x + 1) - (char *)&x))


    Could someone explain why we're casting &x into a char *? Thanks!


    >
    > vishnu mahendra wrote:
    >
    >> can anyone please tell me how to find the size of a variable or a
    >> datatype with out using a sizeof() operatot.
    >> thank you in advance,
    >> vishnu

    >
    >
    Mark, Aug 10, 2003
    #2
    1. Advertising

  3. "Mark" <nospam> wrote in message news:3f36157c$...
    > Atreya, Chaitanya wrote:
    > > #define SIZE(x) ((unsigned int)((char *)(&x + 1) - (char *)&x))

    >
    > Could someone explain why we're casting &x into a char *? Thanks!


    So that the subtraction of the two pointers returns the difference
    in bytes (more specifically, in 'char' units).
    Otherwise it would return the position difference in units
    of type 'x', and the resut of the expression would always be 1.


    hth-ivan
    --
    http://www.post1.com/~ivec
    Ivan Vecerina, Aug 10, 2003
    #3
  4. Atreya, Chaitanya

    Jack Klein Guest

    On Sun, 10 Aug 2003 09:32:20 GMT, "Atreya, Chaitanya"
    <> wrote in comp.lang.c:

    > #define SIZE(x) ((unsigned int)((char *)(&x + 1) - (char *)&x))
    >
    > vishnu mahendra wrote:
    > > can anyone please tell me how to find the size of a variable or a
    > > datatype with out using a sizeof() operatot.
    > > thank you in advance,
    > > vishnu


    This works on variables, but does not work on types.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c /faq
    Jack Klein, Aug 10, 2003
    #4
  5. "Jack Klein" <> wrote in message
    news:...
    > On Sun, 10 Aug 2003 09:32:20 GMT, "Atreya, Chaitanya"
    > <> wrote in comp.lang.c:
    >
    > > #define SIZE(x) ((unsigned int)((char *)(&x + 1) - (char *)&x))
    > >
    > > vishnu mahendra wrote:
    > > > can anyone please tell me how to find the size of a variable or a
    > > > datatype with out using a sizeof() operatot.
    > > > thank you in advance,
    > > > vishnu

    >
    > This works on variables, but does not work on types.
    >


    #define SIZE(type) ((int)((type *)0 + 1))

    works on types, but not variables. Given sizeof(x) works for both, I'd just
    use that...

    > --
    > Jack Klein
    > Home: http://JK-Technology.Com
    > FAQs for
    > comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    > comp.lang.c++ http://www.parashift.com/c -faq-lite/
    > alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c /faq


    --
    Roger
    Roger Willcocks, Aug 11, 2003
    #5
  6. In article <bh6jdv$1an$1$>,
    Roger Willcocks <> wrote:
    >
    >#define SIZE(type) ((int)((type *)0 + 1))
    >
    >works on types, but not variables. Given sizeof(x) works for both, I'd just
    >use that...


    Adding one to a null pointer is undefined behavior, and converting a
    non-null pointer to an integer gives an implementation-defined result.

    So the SIZE macro above doesn't necessarily work for anything.

    -- Brett
    Brett Frankenberger, Aug 11, 2003
    #6
  7. Atreya, Chaitanya

    Dan Pop Guest

    In <bh6tq8$ntc$> "Jun Woong" <> writes:


    >"Roger Willcocks" <> wrote in message news:bh6jdv$1an$1$...
    >>
    >> "Jack Klein" <> wrote in message
    >> news:...

    >[...]
    >> >
    >> > This works on variables, but does not work on types.
    >> >

    >>
    >> #define SIZE(type) ((int)((type *)0 + 1))
    >>
    >> works on types,

    >
    >Only if the undefined behavior invoked is ignored silently.


    Nope! Only if the undefined behaviour happens to coincide with the
    expected behaviour.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, Aug 11, 2003
    #7
  8. (Dan Pop) writes:
    > In <bh6tq8$ntc$> "Jun Woong" <> writes:
    > >"Roger Willcocks" <> wrote in message
    > >news:bh6jdv$1an$1$...
    > >>
    > >> "Jack Klein" <> wrote in message
    > >> news:...

    > >[...]
    > >> >
    > >> > This works on variables, but does not work on types.
    > >> >
    > >>
    > >> #define SIZE(type) ((int)((type *)0 + 1))
    > >>
    > >> works on types,

    > >
    > >Only if the undefined behavior invoked is ignored silently.

    >
    > Nope! Only if the undefined behaviour happens to coincide with the
    > expected behaviour.


    The suggested SIZE() macro is similar to the common implementation of
    the offsetof() macro:

    #define offsetof(s, m) (size_t)(&(((s *)0)->m))

    Both definitions take advantage of undefined behavior that happens to
    work as expected on a given implementation. Since the offsetof()
    macro is part of the implementation, it can legitimately do this kind
    of thing. The SIZE() macro is not, so if you use it, you do so at
    your own risk (and presumably with a very good reason for not using
    the sizeof operator thoughtfully provided by the language itself).

    BTW, the SIZE macro should cast the result to size_t, not int.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
    Schroedinger does Shakespeare: "To be *and* not to be"
    Keith Thompson, Aug 11, 2003
    #8
  9. (Samuel Barber) writes:
    > (Brett Frankenberger) wrote in message
    > news:<bh70bn$aa8$>...
    > > In article <bh6jdv$1an$1$>,
    > > Roger Willcocks <> wrote:
    > > >
    > > >#define SIZE(type) ((int)((type *)0 + 1))
    > > >
    > > >works on types, but not variables. Given sizeof(x) works for both,
    > > >I'd just use that...

    > >
    > > Adding one to a null pointer is undefined behavior, and converting a
    > > non-null pointer to an integer gives an implementation-defined result.

    >
    > #define SIZE(type) ((int)((type *)16 + 1)-16)
    >
    > gets rid of the "null pointer", for what it's worth.


    "What it's worth" is very likely nothing. Adding one to (type*)16 is
    undefined behavior, no more or less than adding one to (type*)0.

    It may be an improvement on implementations where a null pointer is
    not all-bits-zero, but on such an implementation I wouldn't bet on
    (type*)16 behaving as expected either.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
    Schroedinger does Shakespeare: "To be *and* not to be"
    Keith Thompson, Aug 12, 2003
    #9
  10. In article <>,
    Samuel Barber <> wrote:
    > (Brett Frankenberger) wrote in message
    >news:<bh70bn$aa8$>...
    >
    >> So the SIZE macro above doesn't necessarily work for anything.

    >
    >I think you mean "doesn't necessarily work for everything".


    No, I mean it doesn't necessarily work for anything. That is, an
    implementation isn't required to give the expected result for any usage
    of the SIZE macro -- it's undefined behavior in all cases.

    The "necessarily" covers the fact that some (even many) implementations
    may give the expected result or some or all uses of the macro.

    -- Brett
    Brett Frankenberger, Aug 12, 2003
    #10
  11. In article <bh9mjm$>,
    Gordon Burditt <> wrote:
    >>
    >>#define SIZE(type) ((int)((type *)16 + 1)-16)
    >>
    >>gets rid of the "null pointer", for what it's worth.

    >
    >There is no guarantee that (type *) 16 won't segfault (and no, I
    >don't mean *derefrencing* (type *) 16) or otherwise cause a CPU
    >trap. This is especially the case for architectures that require
    >a valid segment number in pointers. (One example of this is the
    >i386 architecture in 32-bit large-memory model (48-bit pointers)).


    There is certainly no guarantee that it won't segfault (or that it will
    do anything at all in particular) ... but many compilers, even on
    architectures where a pointer to address 16 would fault just by being
    loaded into a register, will optimize the expression down to a single
    integer at compile time, so no addresses will get loaded anywhere.

    -- Brett
    Brett Frankenberger, Aug 12, 2003
    #11
  12. Atreya, Chaitanya

    Dan Pop Guest

    In <bhan3m$e4t$> (Brett Frankenberger) writes:

    >In article <bh9mjm$>,
    >Gordon Burditt <> wrote:
    >>>
    >>>#define SIZE(type) ((int)((type *)16 + 1)-16)
    >>>
    >>>gets rid of the "null pointer", for what it's worth.

    >>
    >>There is no guarantee that (type *) 16 won't segfault (and no, I
    >>don't mean *derefrencing* (type *) 16) or otherwise cause a CPU
    >>trap. This is especially the case for architectures that require
    >>a valid segment number in pointers. (One example of this is the
    >>i386 architecture in 32-bit large-memory model (48-bit pointers)).

    >
    >There is certainly no guarantee that it won't segfault (or that it will
    >do anything at all in particular) ... but many compilers, even on
    >architectures where a pointer to address 16 would fault just by being
    >loaded into a register, will optimize the expression down to a single
    >integer at compile time, so no addresses will get loaded anywhere.


    If they do that for 16, why wouldn't they do that for 0, too?

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, Aug 12, 2003
    #12
  13. (Brett Frankenberger) wrote in message news:<bhamtu$e3f$>...
    > In article <>,
    > Samuel Barber <> wrote:
    > > (Brett Frankenberger) wrote in message
    > >news:<bh70bn$aa8$>...
    > >
    > >> So the SIZE macro above doesn't necessarily work for anything.

    > >
    > >I think you mean "doesn't necessarily work for everything".

    >
    > No, I mean it doesn't necessarily work for anything. That is, an
    > implementation isn't required to give the expected result for any usage
    > of the SIZE macro -- it's undefined behavior in all cases.


    No. Casting an integer constant to a pointer is standard practice in C
    (a common case is accessing memory-mapped I/O). Many well-written C
    programs rely on it. What is true is that this sort of thing is best
    avoided if possible, to maximize portability.

    Sam
    Samuel Barber, Aug 12, 2003
    #13
  14. Atreya, Chaitanya

    Dan Pop Guest

    In <> (Samuel Barber) writes:

    > (Brett Frankenberger) wrote in message news:<bhamtu$e3f$>...
    >> In article <>,
    >> Samuel Barber <> wrote:
    >> > (Brett Frankenberger) wrote in message
    >> >news:<bh70bn$aa8$>...
    >> >
    >> >> So the SIZE macro above doesn't necessarily work for anything.
    >> >
    >> >I think you mean "doesn't necessarily work for everything".

    >>
    >> No, I mean it doesn't necessarily work for anything. That is, an
    >> implementation isn't required to give the expected result for any usage
    >> of the SIZE macro -- it's undefined behavior in all cases.

    >
    >No. Casting an integer constant to a pointer is standard practice in C
    >(a common case is accessing memory-mapped I/O).


    It might be standard practice in C, but the result is not guaranteed by
    the C standard (it's implementation-defined).

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, Aug 13, 2003
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Derek
    Replies:
    7
    Views:
    24,296
    Ron Natalie
    Oct 14, 2004
  2. Trevor

    sizeof(str) or sizeof(str) - 1 ?

    Trevor, Apr 3, 2004, in forum: C Programming
    Replies:
    9
    Views:
    610
    CBFalconer
    Apr 10, 2004
  3. Vinu
    Replies:
    13
    Views:
    1,373
    Lawrence Kirby
    May 12, 2005
  4. blufox

    sizeof( int ) != sizeof( void * )

    blufox, May 22, 2006, in forum: C Programming
    Replies:
    2
    Views:
    541
    Joe Smith
    May 22, 2006
  5. Alex Vinokur
    Replies:
    7
    Views:
    481
    Clark S. Cox III
    Aug 14, 2006
Loading...

Share This Page