Why sizeof(main) = 1?

Discussion in 'C Programming' started by Myth__Buster, Dec 17, 2012.

  1. Myth__Buster

    Myth__Buster Guest

    Hi,

    On a Linux system with gcc, I am just wondering why sizeof(main) can
    be 1 or sizeof when applied on any function name can yield 1 ever? Or
    is it only gcc's perspective to say sizeof of an implicit function
    pointer to be 1 since it gives sizeof(void) to be 1 based on the
    backward compatibility with the pre C99 notion that void* had its
    predecessor char* and usually sizeof(char) being 1?

    Also, I tried the invariably buggy code to see if at all sizeof(main)
    = 1 can be realized.

    /* Keep the warnings aside for a minute, please! */
    #include <stdio.h>

    int main(void)
    {
    printf("sizeof(char) : %zd\n", sizeof(char));
    printf("sizeof(main) : %zd\n", sizeof(main));

    char p = main; // Truncates into only one byte of the bytes
    required to hold
    // main's address - known bug. But just
    to see sizeof(main) = 1 if at all makes any sense.

    ((int (*)(void))p)(); // Known to be buggy and wrong.

    return 0;
    }

    Any explanation is cheerful. :)

    Cheers.
    Myth__Buster, Dec 17, 2012
    #1
    1. Advertising

  2. Myth__Buster

    Shao Miller Guest

    On 12/16/2012 21:38, Myth__Buster wrote:
    > On a Linux system with gcc, I am just wondering why sizeof(main) can
    > be 1 or sizeof when applied on any function name can yield 1 ever? Or
    > is it only gcc's perspective to say sizeof of an implicit function
    > pointer to be 1 since it gives sizeof(void) to be 1 based on the
    > backward compatibility with the pre C99 notion that void* had its
    > predecessor char* and usually sizeof(char) being 1?
    >
    > [...]
    >
    >
    > Any explanation is cheerful. :)
    >
    > Cheers.
    >


    Cheers to you, also.

    C has that "The sizeof operator shall not be applied to an expression
    that has function type or an incomplete type, to the parenthesized name
    of such a type, or to an expression that designates a bit-field member."

    If it's somehow still compiling, then what you are getting is undefined
    behaviour, which can be anything at all, including behaviour that has no
    rationale.

    - Shao Miller
    Shao Miller, Dec 17, 2012
    #2
    1. Advertising

  3. Myth__Buster

    James Kuyper Guest

    On 12/16/2012 09:38 PM, Myth__Buster wrote:
    > Hi,
    >
    > On a Linux system with gcc, I am just wondering why sizeof(main) can
    > be 1 or sizeof when applied on any function name can yield 1 ever? Or
    > is it only gcc's perspective to say sizeof of an implicit function
    > pointer to be 1 since it gives sizeof(void) to be 1 based on the
    > backward compatibility with the pre C99 notion that void* had its
    > predecessor char* and usually sizeof(char) being 1?
    >
    > Also, I tried the invariably buggy code to see if at all sizeof(main)
    > = 1 can be realized.
    >
    > /* Keep the warnings aside for a minute, please! */
    > #include <stdio.h>
    >
    > int main(void)
    > {
    > printf("sizeof(char) : %zd\n", sizeof(char));
    > printf("sizeof(main) : %zd\n", sizeof(main));
    >
    > char p = main; // Truncates into only one byte of the bytes
    > required to hold
    > // main's address - known bug. But just
    > to see sizeof(main) = 1 if at all makes any sense.
    >
    > ((int (*)(void))p)(); // Known to be buggy and wrong.
    >
    > return 0;
    > }
    >
    > Any explanation is cheerful. :)


    "Except when it is the operand of the sizeof operator, the _Alignof
    operator,65) or the unary & operator, a function designator with type
    ‘‘function returning type’’ is converted to an expression that has type
    ‘‘pointer to function returning type’’." (6.3.2.1p4)

    Since this is occurring in the operand of the sizeof operator, no such
    conversion occurs. In other words, you're not asking it to give you the
    size of a function pointer, you'reasking it to tell you the size of the
    function itself, something that has no meaning in C:

    "The sizeof operator shall not be applied to an expression that has
    function type ..." 6.5.3.4p1

    Thus, sizeof(main) is a constraint violation. The only thing required of
    a conforming implementation of C that translates such code is that it
    produce at least one diagnostic message. If such an implementation
    decides, after issuing the mandatory diagnostic, to accept the code, it
    can do anything it wants to with it, since the behavior is undefined. It
    could have printed out 1, or 10, or -30, or "NaN" or "Inf" or "this code
    violates a constraint" or the name of the first person you ever made
    love to.
    Once your code violates a constraint, there's not much point in worrying
    about what happens next; the only proper response to a constraint
    violation is to remove it.
    --
    James Kuyper
    James Kuyper, Dec 17, 2012
    #3
  4. Myth__Buster

    Myth__Buster Guest

    On Dec 16, 6:52 pm, Shao Miller <> wrote:
    > On 12/16/2012 21:38, Myth__Buster wrote:
    >
    > > On a Linux system with gcc, I am just wondering why sizeof(main) can
    > > be 1 or sizeof when applied on any function name can yield 1 ever? Or
    > > is it only gcc's perspective to say sizeof of an implicit function
    > > pointer to be 1 since it gives sizeof(void) to be 1 based on the
    > > backward compatibility with the pre C99 notion that void* had its
    > > predecessor char* and usually sizeof(char) being 1?

    >
    > > [...]

    >
    > > Any explanation is cheerful. :)

    >
    > > Cheers.

    >
    > Cheers to you, also.
    >
    > C has that "The sizeof operator shall not be applied to an expression
    > that has function type or an incomplete type, to the parenthesized name
    > of such a type, or to an expression that designates a bit-field member."
    >
    > If it's somehow still compiling, then what you are getting is undefined
    > behaviour, which can be anything at all, including behaviour that has no
    > rationale.
    >
    > - Shao Miller


    Okay, that's cool to know. :)

    Thanks.
    Myth__Buster, Dec 17, 2012
    #4
  5. Myth__Buster

    Myth__Buster Guest

    On Dec 16, 6:53 pm, James Kuyper <> wrote:
    > On 12/16/2012 09:38 PM, Myth__Buster wrote:
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > > Hi,

    >
    > > On a Linux system with gcc, I am just wondering why sizeof(main) can
    > > be 1 or sizeof when applied on any function name can yield 1 ever? Or
    > > is it only gcc's perspective to say sizeof of an implicit function
    > > pointer to be 1 since it gives sizeof(void) to be 1 based on the
    > > backward compatibility with the pre C99 notion that void* had its
    > > predecessor char* and usually sizeof(char) being 1?

    >
    > > Also, I tried the invariably buggy code to see if at all sizeof(main)
    > > = 1 can be realized.

    >
    > > /* Keep the warnings aside for a minute, please! */
    > > #include <stdio.h>

    >
    > > int main(void)
    > > {
    > >         printf("sizeof(char) : %zd\n", sizeof(char));
    > >         printf("sizeof(main) : %zd\n", sizeof(main));

    >
    > >         char p = main; // Truncates into only one byte of thebytes
    > > required to hold
    > >                               // main's address - known bug. But just
    > > to see sizeof(main) = 1 if at all makes any sense.

    >
    > >         ((int (*)(void))p)(); // Known to be buggy and wrong.

    >
    > >         return 0;
    > > }

    >
    > > Any explanation is cheerful. :)

    >
    > "Except when it is the operand of the sizeof operator, the _Alignof
    > operator,65) or the unary & operator, a function designator with type
    > ‘‘function returning type’’ is converted to an expression that has type
    > ‘‘pointer to function returning type’’." (6.3.2.1p4)
    >
    > Since this is occurring in the operand of the sizeof operator, no such
    > conversion occurs. In other words, you're not asking it to give you the
    > size of a function pointer, you'reasking it to tell you the size of the
    > function itself, something that has no meaning in C:
    >
    > "The sizeof operator shall not be applied to an expression that has
    > function type ..." 6.5.3.4p1
    >
    > Thus, sizeof(main) is a constraint violation. The only thing required of
    > a conforming implementation of C that translates such code is that it
    > produce at least one diagnostic message. If such an implementation
    > decides, after issuing the mandatory diagnostic, to accept the code, it
    > can do anything it wants to with it, since the behavior is undefined. It
    > could have printed out 1, or 10, or -30, or "NaN" or "Inf" or "this code
    > violates a constraint" or the name of the first person you ever made
    > love to.
    > Once your code violates a constraint, there's not much point in worrying
    > about what happens next; the only proper response to a constraint
    > violation is to remove it.
    > --
    > James Kuyper


    ". . . or the name of the first person you ever made love to." - how
    imaginative
    you are! :)

    Okay, thanks for the explanation.
    Myth__Buster, Dec 17, 2012
    #5
  6. Myth__Buster

    Shao Miller Guest

    On 12/16/2012 22:05, Myth__Buster wrote:
    > On Dec 16, 6:52 pm, Shao Miller <> wrote:
    >>
    >> If it's somehow still compiling, then what you are getting is undefined
    >> behaviour, which can be anything at all, including behaviour that has no
    >> rationale.
    >>

    >
    > Okay, that's cool to know. :)
    >


    You might very well be right about the relationship to GCC's:

    void * ptr = &ptr;
    ptr++;

    allowance, which is a GCC extension, presumably so that something
    possibly useful and possibly expected happens, though it's non-standard.

    The source code for GCC probably reveals more than a guess could, and
    you might be right: It might be that incomplete object types and
    function types are treated in this manner, regarding "size."

    If you are interested in standard behaviour, you might consider
    compiling your test-cases with something like:

    gcc -std=c99 -pedantic -Wall -Wextra -o progname progname.c

    (Or '-std=c89', for an older standard.) Note that C11 is the current
    standard, but I don't know how far along GCC support for it is.

    - Shao Miller
    Shao Miller, Dec 17, 2012
    #6
  7. Myth__Buster

    Myth__Buster Guest

    On Dec 16, 7:18 pm, Shao Miller <> wrote:
    > On 12/16/2012 22:05, Myth__Buster wrote:
    >
    > > On Dec 16, 6:52 pm, Shao Miller <> wrote:

    >
    > >> If it's somehow still compiling, then what you are getting is undefined
    > >> behaviour, which can be anything at all, including behaviour that has no
    > >> rationale.

    >
    > > Okay, that's cool to know. :)

    >
    > You might very well be right about the relationship to GCC's:
    >
    >    void * ptr = &ptr;
    >    ptr++;
    >


    Nice, self-pointer trick! :)

    > allowance, which is a GCC extension, presumably so that something
    > possibly useful and possibly expected happens, though it's non-standard.
    >
    > The source code for GCC probably reveals more than a guess could, and
    > you might be right: It might be that incomplete object types and
    > function types are treated in this manner, regarding "size."


    Yeah, seems like it opens up doors for wild guesses though! :)

    >
    > If you are interested in standard behaviour, you might consider
    > compiling your test-cases with something like:
    >
    >    gcc -std=c99 -pedantic -Wall -Wextra -o progname progname.c
    >
    > (Or '-std=c89', for an older standard.)  Note that C11 is the current
    > standard, but I don't know how far along GCC support for it is.
    >
    > - Shao Miller


    Okay. Yeah, we can use those compilation flags to stick to the
    standards.

    Cheers.
    Myth__Buster, Dec 17, 2012
    #7
  8. Myth__Buster <> writes:
    > On a Linux system with gcc, I am just wondering why sizeof(main) can
    > be 1 or sizeof when applied on any function name can yield 1 ever? Or
    > is it only gcc's perspective to say sizeof of an implicit function
    > pointer to be 1 since it gives sizeof(void) to be 1 based on the
    > backward compatibility with the pre C99 notion that void* had its
    > predecessor char* and usually sizeof(char) being 1?

    [...]

    gcc, as a non-standard extension, permits arithmetic on pointers of
    type void* and on function pointers. The semantics are that adding
    1 to such a pointer yields a pointer to the immediately following
    byte address in memory.

    Unfortunately, IMHO, it does this by pretending that both void and
    function types have a size of 1.

    If you invoke gcc with the right options, it will warn about attempts
    to apply sizeof to void or to type or expression of function type.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Dec 17, 2012
    #8
  9. Myth__Buster

    Myth__Buster Guest

    On Dec 16, 11:17 pm, Keith Thompson <> wrote:
    > Myth__Buster <> writes:
    > > On a Linux system with gcc, I am just wondering why sizeof(main) can
    > > be 1 or sizeof when applied on any function name can yield 1 ever? Or
    > > is it only gcc's perspective to say sizeof of an implicit function
    > > pointer to be 1 since it gives sizeof(void) to be 1 based on the
    > > backward compatibility with the pre C99 notion that void* had its
    > > predecessor char* and usually sizeof(char) being 1?

    >
    > [...]
    >
    > gcc, as a non-standard extension, permits arithmetic on pointers of
    > type void* and on function pointers.  The semantics are that adding
    > 1 to such a pointer yields a pointer to the immediately following
    > byte address in memory.
    >
    > Unfortunately, IMHO, it does this by pretending that both void and
    > function types have a size of 1.
    >
    > If you invoke gcc with the right options, it will warn about attempts
    > to apply sizeof to void or to type or expression of function type.
    >
    > --
    > Keith Thompson (The_Other_Keith)  <http://www.ghoti.net/~kst>
    >     Will write code for food.
    > "We must do something.  This is something.  Therefore, we must do this."
    >     -- Antony Jay and Jonathan Lynn, "Yes Minister"


    Yup, got it! Thanks for the info. :)
    Myth__Buster, Dec 17, 2012
    #9
    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,325
    Ron Natalie
    Oct 14, 2004
  2. Trevor

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

    Trevor, Apr 3, 2004, in forum: C Programming
    Replies:
    9
    Views:
    626
    CBFalconer
    Apr 10, 2004
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,807
    Smokey Grindel
    Dec 2, 2006
  4. Vinu
    Replies:
    13
    Views:
    1,414
    Lawrence Kirby
    May 12, 2005
  5. blufox

    sizeof( int ) != sizeof( void * )

    blufox, May 22, 2006, in forum: C Programming
    Replies:
    2
    Views:
    554
    Joe Smith
    May 22, 2006
Loading...

Share This Page