1

I'm having a little trouble defining the constants I use in my code in a correct way. Although I read the excellent post Jonathan Leffler over at How do I use extern to share variables between source files?, I seem to have misunderstood something. This is the setup:

/*   constants.h   */
extern int NUM_PARTICLES;
extern int LIGHTSPEED;

This header is used in random.h and main.c, which looks like

#include "constants.h"
int NUM_PARTICLES=104;

in random.h or

#include "constants.h"
int LIGHTSPEED=104;

in main.c, respectively. NUM_PARTICLES is used in main.c in

30:  double ghosts[NUM_PARTICLES][4];
31:  double output[NUM_PARTICLES][3];

Although this thing works, I get the following warnings,

main.c: In function ‘int main()’:
main.c:30:32: warning: ISO C++ forbids variable length array ‘ghosts’ [-Wvla]
main.c:31:32: warning: ISO C++ forbids variable length array ‘output’ [-Wvla]

which is weird, because in my opinion I do give the array a constant value that is known at compilation time. (And usually these array length errors cause some segfaults, which in this case they do not.) Any ideas?

Community
  • 1
  • 1
  • In addition to your problem as such, you have the problem that you are compiling C code as C++, which isn't a good idea. In particular the handling of `const` qualified variables is different between the two. – Jens Gustedt Mar 29 '13 at 21:56
  • Yeah, I had that sneaky feeling that mixing C with C++ would cause some problems, but unfortunately I can't change it ;D – Wojciech Morawiec Mar 29 '13 at 22:02

1 Answers1

5

Short story: this is a quirk of C.

Normally, you would define an integer constant as

const int LIGHTSPEED = 104;

The problem is that according to the language rules this constant is not a constant expression, and thus cannot be used to specify the size of a statically allocated array.

The relevant part of the C standard (6.6/6, I am not making this up) defines what an integer constant expression is:

An integer constant expression shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, and floating constants that are the immediate operands of casts.

There are two solutions for this. The classic one is to use a macro, which simply pastes 104 between the angle brackets before the compiler sees the code, therefore making the array size an integer constant:

#define NUM_PARTICLES 104

The better one (IMO) is to avoid a macro because you can, and use an enum, which is possible (you are using an enumeration constant):

enum { NUM_PARTICLES = 104 };
Jon
  • 428,835
  • 81
  • 738
  • 806