Thread: Why are #define macros commonly used in C?

  1. #1
    Registered User
    Join Date
    Aug 2006
    Posts
    6

    Why are #define macros commonly used in C?

    Why not const variables? In discussions about it, I see nearly everyone saying it's better to use const, yet C programmers seem to use #define all the time for simple constant integers.
    [29] Newbie Questions / Answers ..Updated!.., C++ FAQ Lite
    Last edited by noerrorsfound; 09-08-2009 at 01:06 PM.

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    C != C++, that's the simple answer.
    const integers aren't considered constant expressions in C, so using it, for example, to set the size of an array may not work (it won't work under C90, but it would work in C99).
    They also take up memory, unless the compiler somehow optimizes them away (though I don't think it's allowed to).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    They also take up memory, unless the compiler somehow optimizes them away (though I don't think it's allowed to).
    I don't know about that, but I doubt any global variable could be optimized out, in case some unforeseen file references it. Of course, static global variables probably could be optimized away.

    The simple answer is what Elysia has already said: in C, "const" variables are not constant expressions. Seems strange, but that's the way it is.
    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.

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    No so sure I could see this as a significant "reason" either:

    they don't create new "keywords" in your program.
    And the other ones are a little thin too IMO; this is presented as the reason "why the preprocessor is evil":
    Every #define macro effectively creates a new keyword in every source file and every scope until that symbol is #undefd. The preprocessor lets you create a #define symbol that is always replaced independent of the scope where that symbol appears.
    Which seems to me more like a statement of fact rather than something that is inherently ungood or something. Like, it might have been better to say "be careful and use unique names with define". Also, the advantage of using the preprocessor (that it helps simplify and optimize compiling) is not mentioned.
    Last edited by MK27; 09-08-2009 at 01:26 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by MK27
    And the other ones are a little thin too IMO
    Nonetheless, I regard the first, second and last as being reason enough to prefer the compiler over the preprocessor.

    Quote Originally Posted by MK27
    this is presented as the reason "why the preprocessor is evil":
    (...)
    Which seems to me more like a statement of fact rather than something that is inherently ungood or something.
    He is just stating the corollary of the first and last points listed earlier.

    Quote Originally Posted by MK27
    Like, it might have been better to say "be careful and use unique names with define".
    Rather, I think that it would have been better to add that one should be careful with macro names when macros are used, e.g., by adopting the naming convention of using fully capitalised names for macros.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    Quote Originally Posted by noerrorsfound View Post
    Why not const variables? In discussions about it, I see nearly everyone saying it's better to use const, yet C programmers seem to use #define all the time for simple constant integers.
    I suspect that it is, in part, tradition. There are certainly times when a macro is necessary, but I have seen a number of macros that could just as easily be variables. I've been guilty of using macros where they're not necessary, but I'm getting in the habit of changing. I especially like variables because they come with an explicit type (you can't always know what type an unadorned number will be, nor are there suffixes for all types). I'd much rather do this:
    Code:
    const size_t BLAH = 50;
    than this:
    Code:
    #define BLAH ((size_t)50)
    As for not being able to optimize out, it's true that a compiler would have to keep a copy of the object around, but nothing stops it from replacing references to the variable with a constant value. After all, if another source file modifies the const object, you've got undefined behavior. My versions of gcc and icc do this, although clang doesn't.

    Plus if you're doing C99, you don't even need constant expressions for (local) array sizes anymore.

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Is the C compiler allowed to make an assumption that the value of a const variable won't change and hence replace occurrences of that variable with its value (even though the variable itself isn't eliminated)?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    Quote Originally Posted by Elysia View Post
    Is the C compiler allowed to make an assumption that the value of a const variable won't change and hence replace occurrences of that variable with its value (even though the variable itself isn't eliminated)?
    Yes (unless it's also volatile). If it could change, there'd be no point in using const. While non-normative, footnote 112 in C99 6.7.3p3 makes this pretty clear:
    The implementation may place a const object that is not volatile in a read-only region of storage. Moreover, the implementation need not allocate storage for such an object if its address is never used.
    For fun, this program can be used to see how a particular compiler reacts:
    Code:
    #include <stdio.h>
    
    static const int a = 3;
    
    int main(void)
    {
      int *b;
    
      b = (int *)&a;
      *b = 10;
    
      printf("%d\n", a);
    
      return 0;
    }
    On my system, gcc, clang, and sunstudio all segfault, presumably because "a" is read-only. icc spits out the value 3, indicating that it treated "a" as a macro, more or less.

  9. #9
    Registered User
    Join Date
    Aug 2009
    Posts
    198
    Then why not use a macro in the first place?

  10. #10
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    Quote Originally Posted by MTK View Post
    Then why not use a macro in the first place?
    For the various reasons given above.

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Incompatibilities Between ISO C and ISO C++
    const in C and C++ mean very different things.

    A const in C is just a variable with an attribute of "warn me if I try to modify this".
    For one thing, you can't do this in C.
    Code:
    const int size = 10;
    int myarray[size];
    The only way to give a symbolic name to a numeric constant in C is to use #define.

    This of course is perfectly legal (and encouraged) in C++.

    Oh, and the link is required reading for anyone thinking that C++ is a simple superset of C.
    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.

  12. #12
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    > A const in C is just a variable with an attribute of "warn me if I try to modify this".
    While that's true for type "pointer to const something", it's not true for objects that have const, like "const int" or "const pointer to something". In that case, if you modify it directly, that would be an error, and if you try to modify it through a pointer, it's undefined behavior.
    Last edited by robwhit; 09-09-2009 at 02:42 PM.

  13. #13
    Registered User
    Join Date
    Aug 2006
    Posts
    6
    Quote Originally Posted by Salem View Post
    For one thing, you can't do this in C.
    Code:
    const int size = 10;
    int myarray[size];
    Do you mean that isn't possible in C? Gcc compiles it without any problems.

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You can't do it in C90, but you can do it in C99, which GCC conveniently supports.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Registered User
    Join Date
    Aug 2006
    Posts
    6
    I understand now. Gcc's default mode is "gnu89" which supports C99 features. In c89 mode:
    warning: ISO C90 forbids variable length array ‘myarray’
    Thanks for all the answers to my original question as well.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Order of execution of preprocessor macros
    By DL1 in forum C Programming
    Replies: 2
    Last Post: 04-02-2009, 06:52 PM
  2. parameterized macros vs. functions
    By Tbrez in forum C Programming
    Replies: 3
    Last Post: 04-02-2009, 12:33 PM
  3. Macros inside of macros
    By Chewie8 in forum C Programming
    Replies: 2
    Last Post: 02-24-2008, 03:51 AM
  4. VS2003 Macros: Shortcut key bindings?
    By cboard_member in forum A Brief History of Cprogramming.com
    Replies: 2
    Last Post: 11-27-2006, 11:38 AM
  5. template fn replacements for msg macros
    By Ken Fitlike in forum Windows Programming
    Replies: 17
    Last Post: 10-30-2002, 07:55 AM

Tags for this Thread