Sizeof query

Discussion in 'C Programming' started by Praveen Raj, Sep 15, 2009.

  1. Praveen Raj

    Praveen Raj Guest

    Sir, Is this emulation of sizeof is valid..??

    size_t sizeof_obj = (char*)(&obj + 1) - (char*)(&obj);

    Standard says
    A pointer to an object or incomplete type may be converted to a
    pointer to a different object or incomplete type. If the resulting
    pointer is not correctly aligned for the pointed-to type, the behavior
    is undefined.

    and
    When a pointer to an object is converted to a pointer to a character
    type, the result points to the lowest addressed byte of the object.
    Successive increments of the result, up to the size of the object,
    yield pointers to the remaining bytes of the object.

    +

    If two pointers to objects of the same type are subtracted, the result
    is a signed integral value representing the displacement between the
    pointed-to objects; pointers to successive objects differ by 1. The
    type of the result is defined as ptrdiff_t in the standard header
    <stddef.h>. The value is undefined unless the pointers point to
    objects within the same array; however, if P points to the last member
    of an array, then (P+1)-P has value 1..
     
    Praveen Raj, Sep 15, 2009
    #1
    1. Advertising

  2. Praveen Raj

    Alan Curry Guest

    In article <>,
    Praveen Raj <> wrote:
    >Sir, Is this emulation of sizeof is valid..??
    >
    >size_t sizeof_obj = (char*)(&obj + 1) - (char*)(&obj);


    The only chance for it to go wrong is if the object is bigger than the
    maximum value of ptrdiff_t. Even then, there's a fairly good chance that the
    correct result will appear, after the signed result overflows negative, and
    the negative value is reinterpreted as unsigned when you convert it to
    size_t.

    Trying to test that idea, I found that gcc won't let me declare anything that
    big. Not even if I make it extern, and don't define it anywhere. Or even if I
    make it part of a struct, and then don't declare any instances of the struct.

    The question on everyone's mind will be:
    Is there a reason for emulating sizeof?

    --
    Alan Curry
     
    Alan Curry, Sep 15, 2009
    #2
    1. Advertising

  3. Praveen Raj

    Praveen Raj Guest

    On Sep 15, 3:30 pm, (Alan Curry) wrote:
    > In article <..com>,
    > Praveen Raj  <> wrote:
    >
    > >Sir, Is this emulation of sizeof is valid..??

    >
    > >size_t sizeof_obj = (char*)(&obj + 1) - (char*)(&obj);

    >
    > The only chance for it to go wrong is if the object is bigger than the
    > maximum value of ptrdiff_t. Even then, there's a fairly good chance that the
    > correct result will appear, after the signed result overflows negative, and
    > the negative value is reinterpreted as unsigned when you convert it to
    > size_t.
    >
    > Trying to test that idea, I found that gcc won't let me declare anything that
    > big. Not even if I make it extern, and don't define it anywhere. Or even if I
    > make it part of a struct, and then don't declare any instances of the struct.
    >
    > The question on everyone's mind will be:
    > Is there a reason for emulating sizeof?


    That is a common question asked by companies in there interview's..
    :)
    >
    > --
    > Alan Curry
     
    Praveen Raj, Sep 15, 2009
    #3
  4. In article <>,
    Richard Heathfield <> wrote:

    >The best answer you can give is: "I would use sizeof. That's what it's
    >/for/. And it's guaranteed to be available, even in freestanding
    >implementations."


    I'm baffled as to why you think this is such a bad question.
    Obviously it's not intended to imply that sizeof() might really be
    unavailable. I think it's actually a rather good question, because it
    tests the candidate's understanding of C rather than his ability to
    regurgitate stuff. It also has the potential for useful followup
    questions such as "is it affected by padding between the two array
    elements".

    Of course, its wide circulation on Usenet rather devalues it, but
    provided the candidate can explain it rather than just reproduce it
    then I think it still works.

    -- Richard
    --
    Please remember to mention me / in tapes you leave behind.
     
    Richard Tobin, Sep 15, 2009
    #4
  5. Praveen Raj

    jameskuyper Guest

    Gordon Burditt wrote:
    > >Sir, Is this emulation of sizeof is valid..??
    > >
    > >size_t sizeof_obj = (char*)(&obj + 1) - (char*)(&obj);

    >
    > No. sizeof produces an integer constant expression.
    >
    > Your emulation does not, preventing use of the value in a case of
    > a switch statement, for example.


    For that matter, it doesn't work with type names, either.
     
    jameskuyper, Sep 15, 2009
    #5
  6. Praveen Raj

    Flash Gordon Guest

    Richard Heathfield wrote:
    > In <>, Kenneth Brody
    > wrote:
    >
    >> Richard Heathfield wrote:
    >>> In
    >>>

    > <>,
    >>> Praveen Raj wrote:
    >>>
    >>>> On Sep 15, 3:30 pm, (Alan Curry) wrote:
    >>> <snip>
    >>>
    >>>>> The question on everyone's mind will be:
    >>>>> Is there a reason for emulating sizeof?
    >>>> That is a common question asked by companies in there
    >>>> interview's..
    >>>> :)

    >> [...]
    >>> And if you're feeling suicidal, you can ask the interviewer: "what
    >>> is the return type of main?" I did this once, right at the
    >>> beginning of the interview. The interviewer answered correctly
    >>> (well done, John!),

    >> The Standard defines it as int. However, it is also allowed to be
    >> any "implementation-defined" type as well, thereby allowing "void
    >> main(void)" to be perfectly valid on any given implementation, if
    >> the implementor so desires.
    >>
    >> Do I pass? :)

    >
    > Well, you didn't get anything wrong, but it may have been as well to
    > add: "...but such usage is clearly not portable to all
    > implementations".
    >
    >> However, 5.1.2.2.1 doesn't explicitly say that, if an implementation
    >> has main() defined in "some other implementation-defined manner",
    >> can the implementation disallow the two forms listed by the
    >> Standard?

    >
    > A freestanding implementation can have whatever entry point (point at
    > which control flow enters user code) it likes. If your Acme GreenNose
    > automatic mobile cheese grater's C compiler decides to make its entry
    > point void scratchnsniff(void), well, dem's de breaks.
    >
    >>> and then (rightly) wondered aloud whether I would have walked out
    >>> if he'd got it wrong.

    >> If I were an interviewer and was feeling a bit "evil", I might ask
    >> for the output of the following program when compiled and run on an
    >> EBCDIC system:
    >>
    >> #include <stdio.h>
    >>
    >> int main(void)
    >> {
    >> char new = 'z';
    >>
    >> printf("%c %ld %c\n",new,(long)sizeof(new++),new);
    >>
    >> return(0);
    >> }

    >
    > <previous answer, along the lines of "what's evil about it?", deleted>
    >
    > Ah, the penny just dropped. Yes, okay, that's evil.
    >
    > Gur rivy gjvfg vf, bs pbhefr, gung gur jubyr ropqvp guvat vf n pnaneq.
    > Ohg na vagreivrjrr jbhyq unir gb *xabj* gung gur punenpgre frg znxrf
    > ab qvssrerapr va beqre gb evfx nafjrevat gung jnl.
    >
    > That's a GOOD evil twist.


    Yes, my initial answer (until I read the code) would have been gung V
    qba'g xabj ROPQVP. Nf fbba nf V ernq gur pbqr, ubjrire, gur boivbhf naq
    pbeerpg zvavzny nafjre vf gung vg vf vzcyrzragngvba qrsvarq, ohg will be
    implementation defined.
    --
    Flash Gordon
     
    Flash Gordon, Sep 15, 2009
    #6
  7. Praveen Raj

    Seebs Guest

    On 2009-09-15, Flash Gordon <> wrote:
    (in reference to)
    >>> #include <stdio.h>
    >>>
    >>> int main(void)
    >>> {
    >>> char new = 'z';
    >>>
    >>> printf("%c %ld %c\n",new,(long)sizeof(new++),new);
    >>>
    >>> return(0);
    >>> }


    For extra credit:

    What if you change the sizeof to sizeof(int a[new++])?

    (Assume C99.)

    -s
    --
    Copyright 2009, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
     
    Seebs, Sep 15, 2009
    #7
  8. Seebs <> writes:
    > On 2009-09-15, Flash Gordon <> wrote:
    > (in reference to)
    >>>> #include <stdio.h>
    >>>>
    >>>> int main(void)
    >>>> {
    >>>> char new = 'z';
    >>>>
    >>>> printf("%c %ld %c\n",new,(long)sizeof(new++),new);
    >>>>
    >>>> return(0);
    >>>> }

    >
    > For extra credit:
    >
    > What if you change the sizeof to sizeof(int a[new++])?
    >
    > (Assume C99.)


    A syntax error message from the compiler. ``int a[new++]''
    is a declaration, not an expression.

    I think you mean ``sizeof(int[new++])''.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Sep 15, 2009
    #8
  9. Flash Gordon <> writes:
    > Seebs wrote:
    >> On 2009-09-15, Flash Gordon <> wrote:
    >> (in reference to)
    >>>>> #include <stdio.h>
    >>>>>
    >>>>> int main(void)
    >>>>> {
    >>>>> char new = 'z';
    >>>>>
    >>>>> printf("%c %ld %c\n",new,(long)sizeof(new++),new);
    >>>>>
    >>>>> return(0);
    >>>>> }

    >>
    >> For extra credit:
    >>
    >> What if you change the sizeof to sizeof(int a[new++])?
    >>
    >> (Assume C99.)

    >
    > Undefined behaviour.


    You mean after the required diagnostic for the syntax error?

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Sep 15, 2009
    #9
  10. Praveen Raj

    Seebs Guest

    On 2009-09-15, Keith Thompson <> wrote:
    >> For extra credit:
    >>
    >> What if you change the sizeof to sizeof(int a[new++])?
    >>
    >> (Assume C99.)

    >
    > A syntax error message from the compiler. ``int a[new++]''
    > is a declaration, not an expression.
    >
    > I think you mean ``sizeof(int[new++])''.


    Yup.

    (You can see that I'm mostly back here because I've gotten rusty.)

    -s
    --
    Copyright 2009, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
     
    Seebs, Sep 15, 2009
    #10
  11. Keith Thompson <> writes:

    > Seebs <> writes:
    >> On 2009-09-15, Flash Gordon <> wrote:
    >> (in reference to)
    >>>>> #include <stdio.h>
    >>>>>
    >>>>> int main(void)
    >>>>> {
    >>>>> char new = 'z';
    >>>>>
    >>>>> printf("%c %ld %c\n",new,(long)sizeof(new++),new);
    >>>>>
    >>>>> return(0);
    >>>>> }

    >>
    >> For extra credit:
    >>
    >> What if you change the sizeof to sizeof(int a[new++])?
    >>
    >> (Assume C99.)

    >
    > A syntax error message from the compiler. ``int a[new++]''
    > is a declaration, not an expression.
    >
    > I think you mean ``sizeof(int[new++])''.


    This is really just tidying things up in case anyone is a little
    confused by this. A reader might erroneously conclude that your
    correction replaces the declaration with something that *is* an
    expression.

    It might have been clearer to say that ``int a[new++]'' is a
    declaration, not a type name, since that is what you supply as the
    correction. Of course an expression (specifically a unary expression)
    is also permitted after sizeof, but only the oldest quoted code uses
    that syntax.

    --
    Ben.
     
    Ben Bacarisse, Sep 16, 2009
    #11
  12. On Tue, 15 Sep 2009 05:45:41 -0400, Praveen Raj <>
    wrote:

    > Sir, Is this emulation of sizeof is valid..??
    >
    > size_t sizeof_obj = (char*)(&obj + 1) - (char*)(&obj);


    No. It's likely to work on many implementations, but as the part of the
    standard you quote says,

    > The value is undefined unless the pointers point to
    > objects within the same array; however, if P points to the last member
    > of an array, then (P+1)-P has value 1..


    Unless obj is the last member of an array, the value of sizeof_obj is
    undefined.

    Furthermore, the C99 standard (which is not the one you quoted; I don't
    have my
    hardcopy of the C90 standard available, but I assume that's what you're
    looking at)
    says in 6.5.6p8

    If both the pointer operand and the result point to elements of the
    same array object, or one past the last element of the array object,
    the evaluation shall not produce an overflow; otherwise, the
    behavior is undefined.

    So the expression (&obj + 1) invokes undefined behavior unless obj is a
    member of an array, even without the pointer subtraction.

    The next paragraph of C99 says, "When two pointers are subtracted, both
    shall
    point to elements of the same array object, or one past the last element of
    the array object;

    --
    Morris Keesan --
     
    Morris Keesan, Sep 16, 2009
    #12
  13. On Tue, 15 Sep 2009 11:39:08 -0400, Kenneth Brody <>
    wrote:


    > If I were an interviewer and was feeling a bit "evil", I might ask for
    > the output of the following program when compiled and run on an EBCDIC
    > system:
    >
    > #include <stdio.h>
    >
    > int main(void)
    > {
    > char new = 'z';
    >
    > printf("%c %ld %c\n",new,(long)sizeof(new++),new);
    >
    > return(0);
    > }


    This one is very cute, and has tripped up at least two experts responding
    to it. In fact, the output is well-defined, invoking no implementation-
    defined or undefined behavior.

    Gur ynfg fragrapr bs gur frpbaq cnentencu bs gur qrfpevcgvba
    bs gur fvmrbs bcrengbe fnlf, "Vs gur glcr bs gur bcrenaq vf
    n inevnoyr yratgu neenl glcr, gur bcrenaq vf rinyhngrq;
    bgurejvfr, gur bcrenaq vf abg rinyhngrq naq gur erfhyg vf na
    vagrtre pbafgnag."

    Yvxr bguref, zl svefg gubhtug jnf gung gur orunivbe jnf
    haqrsvarq be vzcyrzragngvba qrsvarq orpnhfr bs gur vaperzrag
    rkcerffvba, ohg gung rkcerffvba vf abg rinyhngrq.

    --
    Morris Keesan --
     
    Morris Keesan, Sep 16, 2009
    #13
  14. "Morris Keesan" <> writes:
    > On Tue, 15 Sep 2009 05:45:41 -0400, Praveen Raj
    > <> wrote:
    >
    >> Sir, Is this emulation of sizeof is valid..??
    >>
    >> size_t sizeof_obj = (char*)(&obj + 1) - (char*)(&obj);

    >
    > No. It's likely to work on many implementations, but as the part of the
    > standard you quote says,
    >
    >> The value is undefined unless the pointers point to
    >> objects within the same array; however, if P points to the last member
    >> of an array, then (P+1)-P has value 1..

    >
    > Unless obj is the last member of an array, the value of sizeof_obj is
    > undefined.


    Ah, but you've missed the key passage. C99 6.5.6p7, in the discussion
    of additive operators, says:

    For the purposes of these operators, a pointer to an object that
    is not an element of an array behaves the same as a pointer to
    the first element of an array of length one with the type of
    the object as its element type.

    C90 has similar wording.

    [snip]

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Sep 16, 2009
    #14
  15. Praveen Raj

    Seebs Guest

    On 2009-09-16, Morris Keesan <> wrote:
    > On Tue, 15 Sep 2009 05:45:41 -0400, Praveen Raj <>
    > wrote:
    >
    >> Sir, Is this emulation of sizeof is valid..??
    >>
    >> size_t sizeof_obj = (char*)(&obj + 1) - (char*)(&obj);

    >
    > No. It's likely to work on many implementations, but as the part of the
    > standard you quote says,
    >
    >> The value is undefined unless the pointers point to
    >> objects within the same array; however, if P points to the last member
    >> of an array, then (P+1)-P has value 1..

    >
    > Unless obj is the last member of an array, the value of sizeof_obj is
    > undefined.


    An object is, for purposes of that, equivalent to an array of one object,
    so "&obj+1" is a defined value which would be the address of the next
    object if there were an array of them.

    > So the expression (&obj + 1) invokes undefined behavior unless obj is a
    > member of an array, even without the pointer subtraction.


    See paragraph 7:
    For the purposes of these operators, a pointer to an object that
    is not an element of an array behaves the same as a pointer to the
    first element of an array of length one with the type of the object
    as its element type.

    -s
    --
    Copyright 2009, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
     
    Seebs, Sep 16, 2009
    #15
  16. On Tue, 15 Sep 2009 22:03:35 -0400, Keith Thompson <> wrote:

    > "Morris Keesan" <> writes:
    >> On Tue, 15 Sep 2009 05:45:41 -0400, Praveen Raj
    >> <> wrote:
    >>
    >>> Sir, Is this emulation of sizeof is valid..??
    >>>
    >>> size_t sizeof_obj = (char*)(&obj + 1) - (char*)(&obj);

    >>
    >> No. It's likely to work on many implementations, but as the part of the
    >> standard you quote says,
    >>
    >>> The value is undefined unless the pointers point to
    >>> objects within the same array; however, if P points to the last member
    >>> of an array, then (P+1)-P has value 1..

    >>
    >> Unless obj is the last member of an array, the value of sizeof_obj is
    >> undefined.

    >
    > Ah, but you've missed the key passage. C99 6.5.6p7, in the discussion
    > of additive operators, says:
    >
    > For the purposes of these operators, a pointer to an object that
    > is not an element of an array behaves the same as a pointer to
    > the first element of an array of length one with the type of
    > the object as its element type.


    Oops. Yes, I have, and yes, it does. That's what I get for not reading
    *all* of a section.

    Never mind.
    --
    Morris Keesan --
     
    Morris Keesan, Sep 16, 2009
    #16
  17. Joe Wright <> writes:
    > Morris Keesan wrote:

    [...]
    >> Gur ynfg fragrapr bs gur frpbaq cnentencu bs gur qrfpevcgvba
    >> bs gur fvmrbs bcrengbe fnlf, "Vs gur glcr bs gur bcrenaq vf
    >> n inevnoyr yratgu neenl glcr, gur bcrenaq vf rinyhngrq;
    >> bgurejvfr, gur bcrenaq vf abg rinyhngrq naq gur erfhyg vf na
    >> vagrtre pbafgnag."
    >>
    >> Yvxr bguref, zl svefg gubhtug jnf gung gur orunivbe jnf
    >> haqrsvarq be vzcyrzragngvba qrsvarq orpnhfr bs gur vaperzrag
    >> rkcerffvba, ohg gung rkcerffvba vf abg rinyhngrq.
    >>

    > Please don't do that again.
    >
    > The last sentence of the second paragraph of the description
    > of the sizeof operator says, "If the type of the operand is
    > a variable length array type, the operand is evaluated;
    > otherwise, the operand is not evaluated and the result is an
    > integer constant."
    >
    > Like others, my first thought was that the behavior was
    > undefined or implementation defined because of the increment
    > expression, but that expression is not evaluated.
    >
    > rot13 is trivial, boring and impolite.


    rot13 is a perfectly legitimate way to discuss something without
    spoiling it for others who might want to figure it out for themselves.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Sep 16, 2009
    #17
  18. Praveen Raj

    Alan Curry Guest

    In article <>,
    Kenneth Brody <> wrote:
    > #include <stdio.h>
    >
    > int main(void)
    > {
    > char new = 'z';
    >
    > printf("%c %ld %c\n",new,(long)sizeof(new++),new);
    >
    > return(0);
    > }


    The hard part being, of course, remembering what sort of automatic
    conversions apply to new++

    I seem to recall these being defined in various circumstances:

    usual arithmetic conversions
    integer promotions
    default argument promotions
    default maze of promotion
    usual twisty conversions

    ....all different.

    Now will one of those result in new++ being an int? It means new=new+1, and
    the 1 is an int. Something could happen.

    Before running the code, I guessed correctly. But I have a feeling it was
    because there were a pair of hidden conversions that cancelled each other
    out, not because there were no hidden conversions at all.

    --
    Alan Curry
     
    Alan Curry, Sep 16, 2009
    #18
  19. On 15 Sep, 11:57, Praveen Raj <> wrote:

    > > The question on everyone's mind will be:
    > > Is there a reason for emulating sizeof?

    >
    > That is a common question asked by companies in there interview's..


    great! So now you know the answer!

    "no, there is no good reason for emulating the behaviour of sizeof"
     
    Nick Keighley, Sep 16, 2009
    #19
  20. In article <> Kenneth Brody <> writes:
    ....
    > >> In <>, Kenneth Brody wrote:

    ....
    > >>> int main(void)
    > >>> {
    > >>> char new = 'z';
    > >>>
    > >>> printf("%c %ld %c\n",new,(long)sizeof(new++),new);
    > >>>
    > >>> return(0);
    > >>> }

    ....
    > I don't see any implementation-defined behavior. Did I miss something in my
    > desire to become evil?


    Isn't sizeof(int) implementation defined?
    --
    dik t. winter, cwi, science park 123, 1098 xg amsterdam, nederland, +31205924131
    home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
     
    Dik T. Winter, Sep 16, 2009
    #20
    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,421
    Ron Natalie
    Oct 14, 2004
  2. Trevor

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

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

    sizeof( int ) != sizeof( void * )

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

Share This Page