-1

I declared a constant global variable 'MEM_PRIMES' and I wanna use it in the struct below as the array elements' number but it errors saying "variably modified 'primes' at file scope.

/* global data */

const unsigned int MEM_PRIMES = 100;

struct{
   char *filename;
   FILE *pfile;
   int nrec;
   unsigned long long primes[MEM_PRIMES];
   size_t index;
}global = {"D:\\C\\C files\\mytext4.bin", NULL, 0, {2ULL, 3ULL, 5ULL}, 3};
Filburt
  • 17,626
  • 12
  • 64
  • 115

3 Answers3

2

const doesn't really ensure that the storage cannot be modified; you can take the address, cast away the const and modify it, so I believe that is why you get the complaint.

#define MEM_PRIMES 100

will fix it and is the C way.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
ryanpattison
  • 6,151
  • 1
  • 21
  • 28
  • 1
    The explanation is likely to be true on modern desktop systems, but it's not really an explanation for why you can't do this with `const` in C. While it may sometimes be true that "you can take the address, cast away the const and modify it", it is undefined behavior to do so, so this is no reason for not allowing you to use `const` variables in this manner. – Crowman Nov 02 '14 at 23:25
  • 1
    The reasons are best described as "historical" :) – M.M Nov 02 '14 at 23:31
0

You just can't do this in C, like you can in C++. You'll have to:

#define MEM_PRIMES 100

or similar.

The actual error message you're getting arises from the fact that you are allowed to have variable length arrays in C99 and later - you're just not allowed to have them at file scope (or in structs at all, for that matter) because the size would need to be determined at compile time. So rather than chewing you out for using a const int instead of an actual constant, your compiler is actually thinking you want a VLA, and telling you that you can't have one here.

Crowman
  • 25,242
  • 5
  • 48
  • 56
0

As others have said, a const int variable is deemed to be a variable in C and cannot be used in contexts where a compile time constant is required, such dimensions of a global array or an array embedded in a structure (nor in a case clause within a switch, nor …).

While #define MEM_PRIMES 100 (suggested by the other answers) will work, I'd use:

enum { MEM_PRIMES = 100 };

The reasons are detailed in static const vs #define.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278