C/C++ question, const versus #define for defining array.

  • C/C++
  • Thread starter uart
  • Start date
  • Tags
    Array
In summary, using a const to declare the size of an array in C will not work as the code will not compile. However, if the const is static and part of the main program, it will work.
  • #1
uart
Science Advisor
2,795
21
I know that it's often considered better practice to use C's "typed constants" instead of "#define" as it may offer better error/type checking. I'm wondering however what happens if a const is used to declare the size of an array. For example consider the two possible methods below.

Code:
#define ListSize 80
typdef int List[ListSize];


Code:
const int ListSize = 80;
typdef int List[ListSize];

The latter doesn't compile in standard C as it doesn't seem to recognize ListSize as a compile-time constant. It does however compile ok in c++, but I'm wondering if it does actually allocate the size specified (80 in this case) right there at compile time?

Does anyone know the nitty gritty on this?

Thanks. :smile:
 
Last edited:
Technology news on Phys.org
  • #2
Don't see how it could make any difference, since at compile time (ASSUMING that the compiler implementation retains the constant in time to use it in the same compiler pass) the statement

typdef int List[ListSize];

is the same (in your example) as

typedef int List[80];

As to your specific question, "compile time" is a bit more complicated than you seem to imply but in any case, NOTHING is actually allocated at compile time. It's put into an object file and the object file is loaded at load time and THEN some things get allocated.

If your questions is does the memory get allocate at load time or at run time, then it may depend on where the statement is (main module vs sub-module) but I think in general it gets allocated at run time as part of memory management.
 
  • #3
Sorry I worded that badly. Yes I know that the memory doesn't get allocated at compile time, what I meant is whether it would be literally using "ListSize" as a constant (80 in this case) at compile time or if it was producing code to dynamically allocate the array based on an inquiry to the value of "ListSize" at load/run time.

It didn't really think it was the latter, but I'm confused about why the code with the "const int ..." statement doesn't compile in standard C (it does however compile in c++). The error it gives in standard C is "variable-sized type declared outside of any function".
 
  • #4
uart said:
It didn't really think it was the latter, but I'm confused about why the code with the "const int ..." statement doesn't compile in standard C (it does however compile in c++).
My guess is in the case of the C++ compiler, in the compile time symbol table, it's treats the const int ListSize also as a define, while the C compiler doesn't treat it as a define.

In terms of allocation at compile time versus run time, it depends on what the operating system's loader is capable of when loading a program. For most operating systems, a typical program includes these sections: code, data, stack, with data separated into initialized data, zeroed data (statics in c), and unitialized data. The loader may be unaware of zeroed data, but the program will contain initialization code to zero out that part of the data section. The zeroed and unitialized data just have size information in a typcial program image (I think a MSDOS type .com program contains everything in one large chunk).
 
  • #5
Here's an interesting little twist to this. The error message "variable-sized type declared outside of any function" seems to imply that it wouldn't be a problem if it was inside a function, but as you know error messages are not always that descriptive.

Well I decided to just test this anyway, and used the "const" to define an array inside the main program and it did actually work correctly.

So in the program preamble (before the code main or any other functions) the code
Code:
const int ListSize = 80;
typdef int List[ListSize];
wont compile in standard C.

However if I scrap the typedef (but leave the const defined there) and then place the following in the main program,
Code:
const int ListSize = 80;
...
int main(void) {
  int myList[ListSize];
  ...
then curiously it does compile without any issue.

I think I'll just have to put this down to a quirk in C and move on. :smile:
 
  • #6
actually, "quirk" may not be quite right in this case as I think it's a specific design decision to require that typedefs NOT have external references. That is, a typedeff has to be self-contained because it is going to just REPLACE code elsewhere and allowing it to have external reference opens up a can of worms for OTHER errors. A #define is NOT taken as an external reference because it is immediately replace by the compiler as the typedef is being stored away to be used to replace code later.
 
  • #7
uart said:
The latter doesn't compile in standard C as it doesn't seem to recognize ListSize as a compile-time constant.
Try making it static. Also, are you compiling to the C99 standard, or the older one?
 
  • #8
Hurkyl said:
Try making it static. Also, are you compiling to the C99 standard, or the older one?

I tried making it static but it didn't change the error.
Unfortunately I don't know if this is C99 or older. I'm using Dev-C++ and the version of "gcc" in its bin directory is 3.4.2

This is not terribly important, I really don't have a problem using #define here. I was just helping my nephew with a trivial C program, basically showing him how to tidy it up by defining types and constant etc. I noticed that he's supposed to be writing it in standard C only but he had the file named ###.cpp. I renamed it to ###.c and the compiler immediately came up with a few errors where some c++ only code had been used. These were all easily fixed but the one with the const just bothered me a bit as to why it had that behavior.

BTW. I've just found a good link on stackoverflow where exactly this topic has been discussed. They seem to have come to the same conclusion as here.

To the question
Which one is better to use among the below statements in c:
static const int var=5;
or
#define var 5

I thought this response was good and very thorough.
It depends on what you need the value for. You (and everyone else so far) omitted the third alternative:

(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.

Ref : http://stackoverflow.com/questions/1674032/static-const-vs-define-in-c
 
Last edited:
  • #9
uart said:
I tried making it static but it didn't change the error.
Unfortunately I don't know if this is C99 or older. I'm using Dev-C++ and the version of "gcc" in its bin directory is 3.4.2
:bugeye: That is an old version of gcc. You can get something a bit more modern that is still free.

Anyhow, the problem here is that 'const' doesn't quite mean 'const' in C. So as far as C is concerned, this is a variable-length array, and variable length arrays are only valid as local variables (i.e., some function's internal variable). You can't use variable length arrays at file scope or as an element of a structure.

BTW. I've just found a good link on stackoverflow where exactly this topic has been discussed. They seem to have come to the same conclusion as here.

I thought this response was good and very thorough.
That answer provides one key alternative to a const int or a #defined value: Use an enum value to size your arrays. This is a compile-time constant to both C and C++.

As far as sizing an array, a "static const int" is not the way to go in C++ unless the array itself has static scope. If the array has extern scope, the array size had also better have extern scope.
 
Last edited:
  • #10
D H said:
As far as sizing an array, a "static const int" is not the way to go in C++ unless the array itself has static scope. If the array has extern scope, the array size had also better have extern scope.
Eh?

Oh, I think I have an idea what you might mean, but it could only be a worry in certain cases. e.g. the following would be just fine, even preferred:

Code:
// myheader.hh
static const size_t my_array_size = 32;
extern int my_array[my_array_size];

// mysource.cc
#include "myheader.hh"

int my_array[my_array_size];
 
  • #11
uart said:
I tried making it static but it didn't change the error.
Oh well. Alas I don't have a convenient C compiler on this computer so I couldn't check myself.


I hadn't realized that particular difference between enum and static const int; interesting.
 

1. What is the difference between using const and #define for defining an array in C/C++?

Const is a keyword that allows you to create a read-only variable in C/C++, meaning that its value cannot be changed once it is initialized. On the other hand, #define is a preprocessor directive that defines a constant value that is replaced by the preprocessor before compilation. In the case of defining an array, using const would create a constant array, whereas using #define would create a macro that can be used to represent the array's size or elements.

2. Which one is better to use, const or #define, for defining an array in C/C++?

It ultimately depends on the specific situation and personal preference. Const is usually preferred as it is a more modern and safer way to create constants in C/C++. It also provides better type checking and can be used with any data type. However, #define can be useful in certain situations, such as defining a constant string, as it allows for string concatenation.

3. Can const and #define be used interchangeably for defining arrays?

No, const and #define cannot be used interchangeably for defining arrays. As mentioned earlier, const creates a constant variable while #define creates a macro. This means that const can only be used for creating a constant array, whereas #define can be used for creating a variable-sized array or a constant array with a specific size or elements.

4. Are there any performance differences between using const and #define for defining arrays?

No, there are no performance differences between using const and #define for defining arrays. Both methods are handled by the preprocessor and do not have any impact on the compiled code's performance.

5. Is there a preferred way to define arrays in C/C++?

As mentioned earlier, it ultimately depends on the specific situation and personal preference. However, const is generally considered a more modern and safer way to define arrays in C/C++. It also allows for better type checking and can be used with any data type, making it a more versatile option.

Similar threads

  • Programming and Computer Science
Replies
17
Views
1K
  • Programming and Computer Science
Replies
23
Views
1K
  • Programming and Computer Science
Replies
31
Views
2K
  • Programming and Computer Science
Replies
3
Views
1K
  • Programming and Computer Science
Replies
12
Views
1K
  • Programming and Computer Science
Replies
1
Views
646
  • Programming and Computer Science
Replies
5
Views
884
  • Programming and Computer Science
Replies
8
Views
8K
  • Programming and Computer Science
Replies
4
Views
2K
  • Programming and Computer Science
Replies
13
Views
2K
Back
Top