Thread: #define vs const

  1. #1
    Registered Abuser
    Join Date
    Jun 2006
    Location
    Toronto
    Posts
    591

    #define vs const

    From what I've read so far on the topic, there seems to be a common consensus that it is good practice to use const inplace of a preprocessor #define when declaring constants. Many of the reasons go on about type checking, and debugging, however, my main curiousity on the difference between the two is memory management on a low level. Since const allocates memory for a variable whereas #define simply does text replacement in the code, when it all comes down to machine language, which makes more effecient use of space, a hardcoded value or a variable?

  2. #2
    Registered User
    Join Date
    May 2006
    Posts
    903
    It doesn't matter. Chances are that when your compiler see the const value, it will consider it the same way as the #define'd value. Leave such small optimizations to your compiler. It knows much better about optimization than any of us.

  3. #3
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065
    If you are on a modern machine, space is not an issue. However, on an embedded system (where space counts), using a const will save you some space since it is a reference and not an inline value. But, the space you save is very minimal.

  4. #4
    Registered Abuser
    Join Date
    Jun 2006
    Location
    Toronto
    Posts
    591
    Practically, I know it should not matter, but it is of much interest to me how the memory management works on a machine code level (i.e. assembley). It would be of great help if someone could clarify exactly what happens on a assembler level when a const is used vs a #define.

  5. #5
    Registered User
    Join Date
    Sep 2001
    Posts
    752
    It isn't allways possible for optomizations to rollout const values, and you really shouldn't assume that it happens... not in C.

    When you declare a const variable, assume that it either gets put on the stack (local variable) or in the .data segment of your program (globals).

    So, in theory, it's a bit more space efficient to use #define.
    Callou collei we'll code the way
    Of prime numbers and pings!

  6. #6
    Registered User
    Join Date
    Sep 2001
    Posts
    752
    Quote Originally Posted by @nthony
    Practically, I know it should not matter, but it is of much interest to me how the memory management works on a machine code level (i.e. assembley). It would be of great help if someone could clarify exactly what happens on a assembler level when a const is used vs a #define.
    You should learn assembly if you really want an understanding of C's memory handling, but here it goes.

    The following assembly is more or less pseudocode. I haven't done any actual assembly in years.

    -------------------------------------------------
    First, an introduction to my assembly pseudocode...
    The data segment contains information which is included in the exe and is loaded into memory when the program is run. It can be roughly though of as 'global' memory.
    The code segment contains information which is included in the exe and is loaded into memory when the program is run. It is the machine code of the program.
    The assembly is very simplified, and I made up the directives and instructions on the fly. Everything after a ';' is meant to be a comment.
    db stands for 'declare byte'. 'dlw' stands for 'declare long word', or 32 bits.

    Inline code.

    Code:
    int main (void) {
       printf("%d\n", 3);
       return 0;
    }
    Translates into something like this:

    Code:
    segment data 
    __string1: 
    db '%d\n\0' ; 4 bytes are allocated in the data segment
    
    segment code
    __main:
    push 3
    push __string1
    call printf
    ret 0
    -----------------------------

    The equivalent 'const' code.
    Code:
    int const i = 3;
    
    int main (void) {
       printf("%d\n", i);
       return 0;
    }
    Code:
    segment data 
    __string1: 
    db '%d\n\0' ; 4 bytes are allocated in the data segment.
    i:
    dlw 3 ; I assume 'int' is a 32-bit value, so 4 more bytes.
    
    segment code
    __main:
    push lookup i ; Note that i is an address value.  So, at the machine level, 
         ; a very basic sort of dereferencing has to happen.  Processors, of course,
         ; are very much optomized for this kind of operation.
    push __string1
    call printf
    ret 0
    So, the inlined code should take up less space in memory, and as a file, because of the smaller data segment.

    ----------------------------------------------

    Before anyone claims that the C compiler will just turn the const code into equivalent #define code, I would like to point out that const and #define are not equivalent. Const neccisarily needs store the variable somewhere in memory so we can do things like this:

    Code:
    int const i = 3;
    
    int main (void) {
       int const * p = &i;
       printf ("%d\n", *p);
       return 0;
    }
    Callou collei we'll code the way
    Of prime numbers and pings!

  7. #7
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065
    how about

    #define "This is a long string that will be used several times in the program."

    I guess I should have clarified that the #define of a string is to what I was refering, not int, char, etc.

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    1. This isn't possible in C

    const int size = 10;
    int myArray[ size ];

    You have to do
    #define size 10
    int myArray[ size ];

    2. macro values are not type checked whereas consts are

    3. You could point at a const, whereas you can't point at a define.

    4. constants are more visible to the debugger. #defines are essentially lost when the pre-processor is run.

    Any more?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Sep 2001
    Posts
    752
    Same principle applies. A pointer takes memory just as much as an int does.

    -------------------------------------------------

    Code:
    int main (void) {
       printf("Hello World!\n");
       return 0;
    }
    Translates into something like this:

    Code:
    segment data 
    __string1: 
    db 'Hello World!\n\0'
    
    segment code
    __main:
    push __string1
    call printf
    ret 0
    -----------------------------

    The equivalent 'const' code.
    Code:
    char const * const S = "Hello World!\n";
    
    int main (void) {
       printf(S);
       return 0;
    }
    Code:
    segment data 
    __string1: 
    db 'Hello World!\n\0'
    S:
    dlw __string1 ; Still 4 extra bytes.
    
    segment code
    __main:
    push lookup S
    call printf
    ret 0
    Callou collei we'll code the way
    Of prime numbers and pings!

  10. #10
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    I sometimes use #defines for strings, as Kennedy mentioned. It's useful for concatenating strings.

    Code:
    #define VERSION "1.00"
    #define FULL_VERSION "program version " VERSION
    
    printf(FULL_VERSION "\n"
        "usage: program [arguments]);
    Another alternative for numbers is to use the "enum hack". I don't like it myself, though, and I'm sure some people agree with me.
    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.

  11. #11
    Registered User
    Join Date
    Sep 2001
    Posts
    752
    Quote Originally Posted by Kennedy
    how about

    #define "This is a long string that will be used several times in the program."

    I guess I should have clarified that the #define of a string is to what I was refering, not int, char, etc.
    Ah, I should point out...
    No matter how many times you use that string, the 'extra space' is still only going to be about 4 bytes, and both versions are going to still end up loading the 70-or-so bytes that that string requires.
    Callou collei we'll code the way
    Of prime numbers and pings!

  12. #12
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Space isn't the only issue. Read Salem's post.
    Quote Originally Posted by Salem
    1. This isn't possible in C

    const int size = 10;
    int myArray[ size ];

    You have to do
    #define size 10
    int myArray[ size ];
    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.

  13. #13
    Registered User OnionKnight's Avatar
    Join Date
    Jan 2005
    Posts
    555
    It has been noted but I thought I should clarify it; consts are always put into memory in C, but in C++ they're only put into memory if they have to.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Pointer within a Struct
    By Bladactania in forum C Programming
    Replies: 11
    Last Post: 04-03-2009, 10:20 PM
  2. Need help with Bitmap Display
    By The Brain in forum Windows Programming
    Replies: 7
    Last Post: 03-23-2009, 05:33 AM
  3. Help me with function call
    By NeMewSys in forum C++ Programming
    Replies: 16
    Last Post: 05-22-2008, 01:53 PM
  4. Accessing syscalls from C
    By lilcoder in forum C Programming
    Replies: 17
    Last Post: 09-19-2007, 02:27 PM
  5. My graphics library
    By stupid_mutt in forum C Programming
    Replies: 3
    Last Post: 11-26-2001, 06:05 PM