You are on page 1of 6

constants - "static const" vs "#define" in C - Stack Overflow

06-Mar-14

sign up log in tour help

careers 2.0

search

Questions

Tags

Tour

Users

Ask Question

Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

Take the 2-minute tour

static const vs #define in C


Which one is better to use among the below statements in C?

147
80

static const int var=5;


or

asked 4 years ago viewed 83434 times active 4 months ago

Community Bulletin
blog Your communities list is now customizable

#define var 5
c constants

share | improve this question

Linked
edited Sep 2 '12 at 9:06 Peter Mortensen 6,964 8 49 79 asked Nov 4 '09 at 14:19 Vijay 16.5k 22 98 198
2

13 Interestingly, this is almost exactly the same question as stackoverflow.com/questions/1637332/staticconst-vs-define. The only difference is that that question is about C++, and this one is about C. Since my answer was C++ specific, I say that makes them not identical, but others may disagree. T.E.D. Nov 4 '09 at 15:09 19 Not identical, definitely. There is a whole lot of areas where C++ allows C syntax for compatibility reasons. In those cases, questions like "what is the best way to do X" will have different answers in C++. E.g. object initialization. MSalters Nov 4 '09 at 15:33

What is the difference between macro constants and constant variables in C? Difference between static const and #define in Objective-C are symbolic constants preprocessed? Recommended to use const static or #define

-4 C/C++ - Is it

11 Answers
Generally speaking:

active

oldest

votes
0 2

#define MY_INT VS const int MY_INT How to decide when n should be a const object or a symbolic constant (macro)? Is a macro made to define constants? Why use macro when same job is done by a variable? in C language? constants in ANSI C

103

static const
Because it respects scope and is type-safe. The only caveat I could see: if you want the variable to be possibly defined on the command line. There is still an alternative:
0 0

#ifdef VAR // Very bad name, not long enough, too general, etc.. static int const var = VAR; #else static int const var = 5; // default value #endif
Whenever possible, instead of macros / ellipsis, use a type-safe alternative. If you really NEED to go with a macro (for example, you want __FILE__ or __LINE__ ), then you'd better name your macro VERY carefully: in its naming convention Boost recommends all upper-case, beginning by the name of the project (here BOOST_), while perusing the library you will notice this is (generally) followed by the name of the particular area (library) then with a meaningful name. It generally makes for lengthy names :) share | improve this answer edited Sep 2 '12 at 9:09 Peter Mortensen 6,964 8 49 79 answered Nov 4 '09 at 14:21 Matthieu M. 92.5k 8 91 231

-4 Using #define symbolic 0

#define or const to define constants in a C header file?

see more linked questions

Related
7 defining static const

structs
412 C#: Static readonly vs

const Agreed - also with #define there's a general danger of mangling code as the preprocessor is not aware of syntax. NeilDurant Nov 4 '09 at 14:27 6 Its better to use #if than #ifdef , but otherwise I agree. +1. Tim Post Nov 4 '09 at 15:32 See this : stackoverflow.com/questions/135069/ regarding the difference. Actually, CCAN has implemented that as part of their style guidelines (one of Rusty's pet peeves). Tim Post Nov 4 '09 at 15:34 This is standard C++ evangelism. The answer below is MUCH clearer in explaining what the options really are and mean. In particular: I just had a problem with "static const". Someone used it to define around 2000 "constants" in a header file. Then this header file was included in around 100 ".c" and ".cpp" files. => 8Mbytes for "consts". Great. Yes I know that you might use a linker to remove unreferenced consts, but then
https://stackoverflow.com/questions/1674032/static-const-vs-define-in-c

3 Is there a way to use

const variables in the definitions of other constants?


8 What are the implications

of using static const instead of #define?


9 static, define, and const

in C
1/6

constants - "static const" vs "#define" in C - Stack Overflow

06-Mar-14

this still leaves you which the "consts" which ARE referenced. Running out of space what's all wrong with this answer. Ingo Blackman Nov 26 '13 at 23:19 @IngoBlackman: With a good compiler, only those static whose address is taken should remain; and if the address is taken one could not have used a #define or enum (no address)... so I really fail to see what alternative could have been used. If you can do away with "compile time evaluation", you might be looking for extern const instead. Matthieu M. Nov 27 '13 at 7:41 show 2 more comments

in C
9 static const vs. #define in

c++ - differences in executable size


1 What is the difference

between static const and const?


4 const in C giving

unpredictable output It depends on what you need the value for. You (and everyone else so far) omitted the third alternative:
0 Global const vs #define.

186

1. static const int var = 5; 2. #define var 5 3. enum { var = 5 }; Ignoring issues about the choice of name, then: If you need to pass a pointer around, you must use (1). Since (2) is apparently an option, you don't need to pass pointers around. Both (1) and (3) have a symbol in the debugger's symbol table - that makes debugging easier. It is more likely that (2) will not have a symbol, leaving you wondering what it is. (1) cannot be used as a dimension for arrays at global scope; both (2) and (3) can. (1) cannot be used as a dimension for static arrays at function scope; both (2) and (3) can. Under C99, all of these can be used for local arrays. Technically, using (1) would imply the use of a VLA (variable-length array), though the dimension referenced by 'var' would of course be fixed at size 5. (1) cannot be used in places like switch statements; both (2) and (3) can. (2) can change code that you didn't want changed because it is used by the preprocessor; both (1) and (3) will not have unexpected side-effects like that. You can detect whether (2) has been set in the preprocessor; neither (1) nor (3) allows that. So, in most contexts, prefer the 'enum' over the alternatives. Otherwise, the first and last bullet points are likely to be the controlling factors - and you have to think harder if you need to satisfy both at once. If you were asking about C++, then you'd use option (1) - the static const - every time. share | improve this answer edited Nov 4 '09 at 15:24 answered Nov 4 '09 at 15:17 Jonathan Leffler 275k 32 268 498

Which is better from a security perspective?


-1 Defining constant with

function in C

Hot Network Questions


How can I capture the true colors of my reef aquarium? C++ code and C version macros Is investing money at the bank just a scam? How can I replace a color in an image? An Apache based forum for website Applying timed functions recursively what is the function of the resistor in the below circuit? Images with all colors if/then/else man page Is Adblock (Plus) a security risk? What happens if the Percent of Apex Used reached 100%? Is the One Rings appearance described in the books? Project Manager asks for complete 100% confidence everytime committing code Testing code with Debug.Assert Undefined Behavior Killed My Cat Intuitive reasoning behind biased ML estimators

32 fantastic list! One drawback with enum is that they're implemented as int ([C99] 6.7.2.2/3). A #define lets you specify unsigned and long with U and L suffixes, and const lets you give a type. enum can cause problems with usual type conversions. Gauthier Mar 1 '11 at 9:33 1 1 (2) people ALWAYS complain about type safety. I never understand why not just use "#define var ((int)5)" and hurray you got type safety with a define. Ingo Blackman Nov 26 '13 at 23:23 Besides what @Gauthier says, alternatives (1) and (2) can be used for non-integer constants as well. Joachim Pileborg Jan 2 at 9:41 What about memory usage in space contrived environments? Is only #define guaranteed to not consume any extra space? RedX Feb 7 at 14:46 @RedX: you would have to be in a very peculiar environment for space to a concern. That said, neither enum nor #define uses extra space, per se. The value will appear in the object code as part of the instructions rather than being allocated storage in the data segment or in heap or on the stack. You'll have some space allocated for the static const int , but the compiler might optimize it away if you don't take an address. Jonathan Leffler Feb 7 at 15:04 show 5 more comments

In C, specifically? In C the correct answer is: use #define (or, if appropriate, enum )

49

While it is beneficial to have the scoping and typing properties of a const object, in reality const objects in C (as opposed to C++) are not true constants and therefore are usually useless in most practical cases. So, in C the choice should be determined by how you plan to use your constant. For example, you can't use a const int object as a case label (while a macro will work). You can't use a const int object as a bit-field width (while a macro will work). In C89/90 you can't use a const object to specify an array size (while a macro will work). Even in C99 you can't use a const object to specify an array size when you need a non-VLA array. If this is important for you then it will determine your choice. Most of the time, you'll have no choice but to use #define in C. And don't forget another alternative, that produces true constants in C - enum . In C++ const objects are true constants, so in C++ it is almost always better to prefer the const variant (no need for explicit static in C++ though). share | improve this answer edited Sep 2 '12 at 9:16 Peter Mortensen answered Nov 4 '09 at 14:33 AndreyT

What actually causes a Stack Overflow error? Is it generally acceptable to expose LDAP in read only mode to the Internet? Why should I use a pointer rather than the object itself? After Hoth, why did Vader pursue the Millenium Falcon instead of Luke's X-Wing? Ultimate Tic-Tac-Toe in C Digital IO pin as ground What key does the symbol "" represent?

https://stackoverflow.com/questions/1674032/static-const-vs-define-in-c

2/6

constants - "static const" vs "#define" in C - Stack Overflow

06-Mar-14

6,964 8 49 79

131k 13 170 363

3 "you can't use a const int object as a case label (while a macro will work) " ---> Regarding this statement i tested a const int variable in C in switch- case it is working .... john Feb 10 '12 at 6:24 3 @john: Well, you need to provide the code that you tested and name the specific compiler. Using const int objects in case-labels is illegal in all versions of C language. (Of course, your compiler is free to support it as a non-standard C++-like language extension.) AndreyT Feb 10 '12 at 23:46 "... and therefore are usually useless in most practical cases." I disagree. They're perfectly useful as long as you don't need to use the name as a constant expression. The word "constant" in C means something that can be evaluated at compile time; const means read-only. const int r = rand(); is perfectly legal. Keith Thompson Feb 26 at 16:51

Why does a remote car key work when held to your head/body?

If you can get away with it, static const has a lot of advantages. It obeys the normal scope principles, is visible in a debugger, and generally obeys the rules that variables obey. However, at least in the original C standard, it isn't actually a constant. If you use #define var 5 , you can write int foo[var]; as a declaration, but you can't do that (except as a compiler extension" with static const int var = 5; . This is not the case in C++, where the static const version can be used anywhere the #define version can, and I believe this is also the case with C99. However, never name a #define constant with a lowercase name. It will override any possible use of that name until the end of the translation unit. Macro constants should be in what is effectively their own namespace, which is traditionally all capital letters, perhaps with a prefix. share | improve this answer answered Nov 4 '09 at 14:38 David Thornley 37.8k 6 53 114

5 Unfortunately, this is not the case with C99. const in C99 is still not a real constant. You can declare array size with a const in C99, but only because C99 supports Variable Length Arrays. For this reason, it will only work where VLAs are allowed. For example, even in C99, you still can't use a const to declare size of a member array in a struct . AndreyT Nov 6 '09 at 0:25

In C #define is much more popular. You can use those values for declaring array sizes for example:

#define MAXLEN 5 void foo(void) { int bar[MAXLEN]; }


ANSI C doesn't allow you to use static const s in this context as far as I know. In C++ you should avoid macros in these cases. You can write

const int maxlen = 5; void foo() { int bar[maxlen]; }


and even leave out static because internal linkage is implied by const already [in C++ only]. share | improve this answer edited Jan 21 '11 at 21:06 answered Nov 4 '09 at 14:32 sellibitze 13k 1 24 46

What do you mean with "internal linkage"? I can have const int MY_CONSTANT = 5; in one file and access it with extern const int MY_CONSTANT; in another. I could not find any info in the standard (C99 at least) about const changing the default behaviour "6.2.2:5 If the declaration of an identier for an object has le scope and no storage-class specier, its linkage is external". Gauthier Jan 19 '11 at 12:10 @Gauthier: Sorry, about that. I should have said "is implied by const already in the C++ language". This is specific to C++. sellibitze Jan 21 '11 at 21:05 @sellibitze it's nice to see some arguments along the way instead of tons of OPINION If there would be bonus for true arguments, you got it! Paul Feb 16 at 13:07 As of C99, your second snippet is legal. bar is a VLA (variable length array); the compiler is likely to generate code as if its length were constant. Keith Thompson Feb 26 at 16:53

The difference between static const and #define is that the former uses the memory and the later does not use the memory for storage. Secondly, you cannot pass the address of an #define whereas you can pass the address of a static const . Actually it is depending on what circumstance
3/6

https://stackoverflow.com/questions/1674032/static-const-vs-define-in-c

constants - "static const" vs "#define" in C - Stack Overflow

06-Mar-14

we are under, we need to select one among these two. Both are at their best under different circumstances. Please don't assume that one is better than the other... :-) If that would have been the case, Dennis Ritchie would have kept the best one alone... hahaha... :-) share | improve this answer edited Sep 2 '12 at 9:30 Peter Mortensen 6,964 8 49 79 answered Nov 5 '09 at 15:36 wrapperm 368 2 14

1 +1 for mentioning memory, some embedded systems still don't have that much, though I would probably start off using static consts and only change to #defines if needed. fluffyben Mar 7 '12 at 11:36

Another drawback of const in C is that you can't use the value in initializing another const .

static int const NUMBER_OF_FINGERS_PER_HAND = 5; static int const NUMBER_OF_HANDS = 2; // initializer element is not constant, this does not work. static int const NUMBER_OF_FINGERS = NUMBER_OF_FINGERS_PER_HAND * NUMBER_OF_HANDS;
Even this does not work with a const since the compiler does not see it as a constant:

static uint8_t const ARRAY_SIZE = 16; static int8_t const lookup_table[ARRAY_SIZE] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; // ARRAY_SIZE not a constant!
I'd be happy to use typed const in these cases, otherwise... share | improve this answer edited Jan 24 '11 at 13:32 answered Jan 19 '11 at 10:27 Gauthier 5,849 2 17 34

3 A little late to the game, but this question came up in another question. Chasing down why your static uint8_t const ARRAY_SIZE = 16; all of a sudden no longer compiles can be a bit challenging, particularly when the #define ARRAY_SIZE 256 is buried ten layers deep in a tangled web of headers. That all caps name ARRAY_SIZE is asking for trouble. Reserve ALL_CAPS for macros, and never define a macro that is not in ALL_CAPS form. David Hammen Sep 3 '11 at 2:35 @David: sound advice, which I will follow. Gauthier Sep 5 '11 at 7:02

Don't think there's an answer for "which is always best" but, as Matthieu said

static const
is type safe. My biggest pet peeve with #define , though, is when debugging in Visual Studio you cannot watch the variable. It gives an error that the symbol cannot be found. share | improve this answer edited Sep 2 '12 at 9:11 Peter Mortensen 6,964 8 49 79 answered Nov 4 '09 at 14:25 Afcrowe 59 3

Incidentally, an alternative to #define , which provides proper scoping but behaves like a "real" constant, is "enum". For example:

enum {number_ten = 10;}


In many cases, it's useful to define enumerated types and create variables of those types; if that is done, debuggers may be able to display variables according to their enumeration name. One important caveat with doing that, however: in C++, enumerated types have limited compatibility with integers. For example, by default, one cannot perform arithmetic upon them. I find that to be a curious default behavior for enums; while it would have been nice to have a "strict enum" type, given the desire to have C++ generally compatible with C, I would think the default behavior of an "enum" type should be interchangeable with integers. share | improve this answer edited Sep 2 '12 at 9:32 Peter Mortensen 6,964 8 49 79 answered Jan 1 '11 at 18:00 supercat 23.1k 26 48

In C, enumeration constants are always of type int , so the "enum hack" can't be used with other integer types. (The enumeration type is compatible with some implementation-defined integer type, not necessarily int , but in this case the type is anonymous so that doesn't matter.) Keith Thompson Feb 26 at 16:49 @KeithThompson: Since I wrote the above, I've read that MISRA-C will squawk if a compiler assigns a type
https://stackoverflow.com/questions/1674032/static-const-vs-define-in-c 4/6

constants - "static const" vs "#define" in C - Stack Overflow

06-Mar-14

@KeithThompson: Since I wrote the above, I've read that MISRA-C will squawk if a compiler assigns a type other than int to an enumeration-typed variable (which compilers are allowed to do) and one tries to assign to such a variable a member of its own enumeration. I wish standards committees would add portable ways of declaring integer types with specified semantics. ANY platform, regardless of char size, should be able to e.g. declare a type which will wrap mod 65536, even if the compiler has to add lots of AND R0,#0xFFFF or equivalent instructions. supercat Feb 26 at 17:09 You can use uint16_t , though of course that's not an enumeration type. It would be nice to let the user specify the integer type used to represent a given enumeration type, but you can achieve much of the same effect with a typedef for uint16_t and a series of #define s for individual values. Keith Thompson Feb 26 at 17:12 @KeithThompson: I understand that for historical reasons, we're stuck with the fact that some platforms will evaluate 2U < -1L as true and others as false, and we're now stuck with the fact that a some platforms will implement a comparison between uint32_t and int32_t as signed and some as unsigned, but that doesn't mean the Committee couldn't define an upwardly-compatible successor to C that includes types whose semantics would be consistent on all compilers. supercat Feb 26 at 17:16

#define var 5 will cause you trouble if you have things like mystruct.var .

For example,

struct mystruct { int var; }; #define var 5 int main() { struct mystruct foo; foo.var = 1; return 0; }
The preprocessor will replace it and the code won't compile. For this reason, traditional coding style suggest all constant #define s uses capital letters to avoid conflict. share | improve this answer edited Sep 2 '12 at 9:33 Peter Mortensen 6,964 8 49 79 answered May 13 '12 at 23:16 Calvin 243 2 5

edit: I edited this answer due to the comment of ugoren.

The definition

const int const_value = 5;


does not always define a constant value. Some compilers (for example tcc 0.9.26) just allocate memory identified with the name "const_value". Using the identifier "const_value" you can not modify this memory. But you still could modify the memory using another identifier:

const int const_value = 5; int *mutable_value = (int*) &const_value; *mutable_value = 3; printf("%i", const_value); // output may be 5 or 3, depending on compiler
This means the definition

#define CONST_VALUE 5
is the only way to define a constant value which can not be modiefied by any means. share | improve this answer edited Oct 19 '13 at 7:20 answered Jun 12 '13 at 13:06 user2229691 31 3

5 Modifying a constant value using a pointer is undefined behavior. If you're willing to go there, #define can also be modified, by editing the machine code. ugoren Jun 12 '13 at 13:57 You're partly right. I tested the code with Visual Studio 2012 and it prints 5 . But one can't modify #define because it's a preprocessor macro. It doesn't exist in the binary program. If one wanted to modify all places where CONST_VALUE was used, one had to do it one by one. user2229691 Oct 19 '13 at 7:28 @ugoren: Suppose you write #define CONST 5 , then if (CONST == 5) { do_this(); } else { do_that(); } , and the compiler eliminates the else branch. How do you propose to edit the machine code to change CONST to 6? Keith Thompson Feb 26 at 16:47 @KeithThompson, I never said it can be done easily and reliably. Just that #define isn't bullet-proof. ugoren Feb 26 at 18:12

https://stackoverflow.com/questions/1674032/static-const-vs-define-in-c

5/6

constants - "static const" vs "#define" in C - Stack Overflow

06-Mar-14

@ugoren: My point is that "editing the machine code" is not a sensible way to duplicate the effect of changing the value of a #define . The only real way to do that is to edit the source code and recompile. Keith Thompson Feb 26 at 19:04

Your Answer

Sign up or log in
Sign up using Google Sign up using Facebook Sign up using Stack Exchange

Post as a guest
Name Email

Post Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged c constants or ask your own question.
question feed

about help badges blog chat data legal privacy policy jobs advertising info mobile contact us feedback
TECHNOLOGY Stack Overflow Server Fault Super User Web Applications Ask Ubuntu Webmasters Game Development TeX - LaTeX Programmers Unix & Linux Ask Different (Apple) WordPress Development Geographic Information Systems Electrical Engineering Android Enthusiasts Information Security Database Administrators Drupal Answers SharePoint User Experience Mathematica more (14) LIFE / ARTS Photography Science Fiction & Fantasy Seasoned Advice (cooking) Home Improvement Personal Finance & Money more (12) CULTURE / RECREATION English Language & Usage Skeptics Mi Yodeya (Judaism) Travel Christianity Arqade (gaming) Bicycles Role-playing Games more (21) SCIENCE Mathematics Cross Validated (stats) Theoretical Computer Science Physics MathOverflow more (7) OTHER Stack Apps Meta Stack Overflow Area 51 Stack Overflow Careers

site design / logo 2014 stack exchange inc; user contributions licensed under cc by-sa 3.0 with attribution required
rev 2014.3.5.1422

https://stackoverflow.com/questions/1674032/static-const-vs-define-in-c

6/6

You might also like