Thread: mixing code with declarations

  1. #1
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129

    mixing code with declarations

    Code:
    #include <stdio.h>
    
    int main()
    {
        int p = getchar();
        int er = getchar();
        er++ && p++; /* silence warnings */
        return 0;
    }
    I thought that you couldn't mix code with declarations, but this compiles with no warnings. But when you put in a standalone function in between the declarations, then it does. Why is this?

    If anybody knows the section in C89 where this is explained, please tell.

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    If anybody knows the section in C89 where this is explained, please tell.
    I don't know C standard but would you be surprised if this compiled without warnings?
    Code:
    int p = 1;
    int er = 2;
    So, what's the difference?
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  3. #3
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    The difference is that (I thought) the stack would be constructed in one swoop, like resetting the stack pointer or something. So it would make sense to put it in the language that all the variables must be declared at the beginning of the scope, so that stack allocation optimization would be easy. Initialization of constants is just a memcpy or zero-fill, also easily optimized.

    But when you have returns from functions, the initialization's value is indeterminate, so you can't optimize it. So it would have to be just a regular assignment operation.

    So what is the difference between:
    Code:
    #include <stdio.h>
    int func(int i){return i++;}
    int main()
    {
    	int p = getchar();
    	int er = func(p);
    	er++ && p++; /* silence warnings */
    	return 0;
    }
    which C89 allows... and
    Code:
    #include <stdio.h>
    int func(int i){return i++;}
    int main()
    {
    	int p;
            p = getchar();
    	int er = func(p);
    	er++ && p++; /* silence warnings */
    	return 0;
    }
    which C89 does not allow?

    If you allow function initializations, why not allow declarations interspersed with code?
    Last edited by robwhit; 01-30-2008 at 10:46 AM. Reason: sp

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I have no idea what the reasoning is, but yes, robwhit's first example is correct, the second one will not compile in C89.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    I've been thinking about this and I think I'll answer my own question.

    Using function initializations does not preclude the compiler from allocating the stack in one swoop. It could do that, with the variables rearranged to have consecutive zero-filled variables and memcpy'ied variables, respectively.

    Then the function inits would be called and performed after the declaration block, like they would have if they were in code and not in the declaration block. That way, you get optimizations and function initializations.

  6. #6
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Thanks!

    I guess that makes sense...

  7. #7
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Quote Originally Posted by robwhit View Post
    I've been thinking about this and I think I'll answer my own question.

    Using function initializations does not preclude the compiler from allocating the stack in one swoop. It could do that, with the variables rearranged to have consecutive zero-filled variables and memcpy'ied variables, respectively.

    Then the function inits would be called and performed after the declaration block, like they would have if they were in code and not in the declaration block. That way, you get optimizations and function initializations.
    Quote Originally Posted by robwhit View Post
    Thanks!

    I guess that makes sense...
    You thank yourself for answering your own question?

    Anyway, I'm not sure the C language would be entirely defined with specific compiler optimizations in mind. I thought that local uninitialized variables were not zero-filled or anything.

    Logically, if you initialize a variable with the return value of a function, you do run code - but in a different function. If initializing with a literal or another variable is acceptable, there seems no reason to disallow initializing with the return value of a function call.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  8. #8
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Quote Originally Posted by anon View Post
    You thank yourself for answering your own question?
    I think robwit typed up his first response before noticing matsp's response, and then posted a new post replying to matsp. You're right, it does look funny at first, though. (That's what the edit button is for . . . .)

    Either that or robwit has a split personality or something, or (more likely) more than one person is using his account. Nah, probably not.

    Anyway, I'm not sure the C language would be entirely defined with specific compiler optimizations in mind. I thought that local uninitialized variables were not zero-filled or anything.
    Yes, that is true. But the increment operator ++ exists mostly because the original PDP-10s or whatever the model number was had an instruction for it, at a time when most other computers did not. IIRC.

    Logically, if you initialize a variable with the return value of a function, you do run code - but in a different function. If initializing with a literal or a simple variable is acceptable, there seems no reason to disallow initializing with the return value of a function call.
    Yeah, well, what about this?
    Code:
    int period = use_radians() ? atan(1.0)*4.0 : 360.0
    Looks like code to me.

    As for the original question: I'm not sure why it works, either. However, I'm pretty sure that the compiler treats
    Code:
    int x = 3, y = 4;
    as
    Code:
    int x, y;
    x = 3, y = 4;
    But that's just an impression.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  9. #9
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    You can't mix declarations with STATEMENTS. This doesn't mean you can't call code.

  10. #10
    Madly in anger with you
    Join Date
    Nov 2005
    Posts
    211
    actually, you can't just call code, when I was debugging an app not long ago, I did one of these:

    Code:
    int main(void)
    {
        somefunc();
        int i;
    
        return 0;
    }
    and was recieving some weird error. turns out my compiler only supported C89, and somefunc couldn't be called before the declarations (the error was resolved when I called somefunc after the declarations, and no, somefunc did not use any of the declared variables).

    dwks is probably right, a statement looking like this:

    Code:
    int period = use_radians() ? atan(1.0)*4.0 : 360.0;
    is probably unfolded at compile time to something like this:

    Code:
    /* declaration block */
    int period;
    /* ... */
    
    /* initialization block */
    period =  use_radians() ? atan(1.0)*4.0 : 360.0;
    /* ... */
    which explains why it works. the compiler is probably arranging the code accordingly, so that the initializations will always be executed immediately after declarations (before any further code that might use the variables declared and initialized will be executed).

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I have a strong feeling that the C language parser becomes quite a lot easier to write when you don't have to check if a line is a variable declaration as well as parse regular function calls etc. This is probably a large part of the reasoning. Of course, wich C++ arriving, the compiler had to support "variables declared anywhere", so it was quite easy to back-port that into the regular C compiler, hence the C99 allows this.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by sl34k View Post
    actually, you can't just call code
    Pretty much what I said. A line consisting of just a function call is a statement, not a declaration.

  13. #13
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    >You thank yourself for answering your own question?
    yeah, I was just poking fun at myself.

    >I thought that local uninitialized variables were not zero-filled or anything.
    I meant initialized to zero would be zero-filled.

    >I think robwit typed up his first response before noticing matsp's response, and then posted a new post replying to matsp. You're right, it does look funny at first, though. (That's what the edit button is for . . . .)
    Thanks for giving me the benefit of the doubt.

    I think matsp's idea is the most probable.

    Thanks for responding to this, everybody. It has helped me to understand this better.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Does gcc hate Forward declarations?
    By SevenThunders in forum C++ Programming
    Replies: 12
    Last Post: 03-16-2009, 02:03 PM
  2. Obfuscated Code Contest: The Results
    By Stack Overflow in forum Contests Board
    Replies: 29
    Last Post: 02-18-2005, 05:39 PM
  3. Obfuscated Code Contest
    By Stack Overflow in forum Contests Board
    Replies: 51
    Last Post: 01-21-2005, 04:17 PM
  4. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM