C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 09-08-2009, 01:04 PM   #1
Registered User
 
Join Date: Aug 2006
Posts: 7
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.
noerrorsfound is offline   Reply With Quote
Old 09-08-2009, 01:09 PM   #2
Mysterious C++ User
 
Join Date: Oct 2007
Posts: 14,099
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).
__________________
Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System
I dedicated my life to helping others. This is only a small sample of what they said:
"Thanks Elysia. You're a programming master! How the hell do you know every thing?"
Quoted... at least once.
Quote:
Originally Posted by cpjust
If C++ is 2 steps forward from C, then I'd say Java is 1 step forward and 2 steps back.
Elysia is offline   Reply With Quote
Old 09-08-2009, 01:22 PM   #3
Frequently Quite Prolix
 
dwks's Avatar
 
Join Date: Apr 2005
Location: Canada
Posts: 7,629
Quote:
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, etc.

New project: nort
dwks is offline   Reply With Quote
Old 09-08-2009, 01:24 PM   #4
subminimalist
 
MK27's Avatar
 
Join Date: Jul 2008
Location: NYC
Posts: 3,944
No so sure I could see this as a significant "reason" either:

Quote:
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":
Quote:
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.
__________________

Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS

Last edited by MK27; 09-08-2009 at 01:26 PM.
MK27 is online now   Reply With Quote
Old 09-08-2009, 01:57 PM   #5
C++ Witch
 
laserlight's Avatar
 
Join Date: Oct 2003
Location: Singapore
Posts: 10,365
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.
__________________
C + C++ Compiler: MinGW port of GCC
Build + Version Control System: SCons + Bazaar

Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
laserlight is online now   Reply With Quote
Old 09-08-2009, 05:13 PM   #6
cas
Registered User
 
Join Date: Sep 2007
Posts: 372
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.
cas is offline   Reply With Quote
Old 09-09-2009, 11:29 AM   #7
Mysterious C++ User
 
Join Date: Oct 2007
Posts: 14,099
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)?
__________________
Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System
I dedicated my life to helping others. This is only a small sample of what they said:
"Thanks Elysia. You're a programming master! How the hell do you know every thing?"
Quoted... at least once.
Quote:
Originally Posted by cpjust
If C++ is 2 steps forward from C, then I'd say Java is 1 step forward and 2 steps back.
Elysia is offline   Reply With Quote
Old 09-09-2009, 12:00 PM   #8
cas
Registered User
 
Join Date: Sep 2007
Posts: 372
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:
Quote:
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.
cas is offline   Reply With Quote
Old 09-09-2009, 12:30 PM   #9
MTK
Registered User
 
Join Date: Aug 2009
Posts: 135
Then why not use a macro in the first place?
__________________
My Platform: Fedora 11 GNU/Linux, GNU GCC Compiler
MTK is offline   Reply With Quote
Old 09-09-2009, 01:53 PM   #10
cas
Registered User
 
Join Date: Sep 2007
Posts: 372
Quote:
Originally Posted by MTK View Post
Then why not use a macro in the first place?
For the various reasons given above.
cas is offline   Reply With Quote
Old 09-09-2009, 02:03 PM   #11
and the hat of vanishing
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,214
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.
Up to 8Mb PlusNet broadband from only £5.99 a month!
Salem is offline   Reply With Quote
Old 09-09-2009, 02:37 PM   #12
Registered User
 
Join Date: Oct 2001
Posts: 2,110
> 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.
robwhit is offline   Reply With Quote
Old 09-11-2009, 02:41 PM   #13
Registered User
 
Join Date: Aug 2006
Posts: 7
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.
noerrorsfound is offline   Reply With Quote
Old 09-11-2009, 02:43 PM   #14
Mysterious C++ User
 
Join Date: Oct 2007
Posts: 14,099
You can't do it in C90, but you can do it in C99, which GCC conveniently supports.
__________________
Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System
I dedicated my life to helping others. This is only a small sample of what they said:
"Thanks Elysia. You're a programming master! How the hell do you know every thing?"
Quoted... at least once.
Quote:
Originally Posted by cpjust
If C++ is 2 steps forward from C, then I'd say Java is 1 step forward and 2 steps back.
Elysia is offline   Reply With Quote
Old 09-11-2009, 02:49 PM   #15
Registered User
 
Join Date: Aug 2006
Posts: 7
I understand now. Gcc's default mode is "gnu89" which supports C99 features. In c89 mode:
Quote:
warning: ISO C90 forbids variable length array ‘myarray’
Thanks for all the answers to my original question as well.
noerrorsfound is offline   Reply With Quote
Reply

Tags
const, define, macros

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Order of execution of preprocessor macros DL1 C Programming 2 04-02-2009 06:52 PM
parameterized macros vs. functions Tbrez C Programming 3 04-02-2009 12:33 PM
Macros inside of macros Chewie8 C Programming 2 02-24-2008 03:51 AM
VS2003 Macros: Shortcut key bindings? ahluka General Discussions 2 11-27-2006 11:38 AM
template fn replacements for msg macros Ken Fitlike Windows Programming 17 10-30-2002 07:55 AM


All times are GMT -6. The time now is 07:20 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22