0

I have declared and initialized a struct at the top of the file like so:

struct myDataTypes {
    int INT;
    int DOUBLE;
    int FLOAT;
} types = {0,1,2};

When I try to use types.INT in a case of a switch, I get the compiler error that the case label does not reduce to an integer constant. Is that it, struct members cannot work as integer constants?

BTW, I'm using a struct for this rather than an enum because enums pollute the global namespace. I prefer the way I can hide INT, DOUBLE, FLOAT in a struct.

Theo d'Or
  • 783
  • 1
  • 4
  • 17
  • Does this answer your question? [switch case: error: case label does not reduce to an integer constant](https://stackoverflow.com/questions/14069737/switch-case-error-case-label-does-not-reduce-to-an-integer-constant) – Sander De Dycker Jan 22 '20 at 10:05
  • @SanderDeDycker It doesn't help because it doesn't address structs specifically, and the generic info found in that Q&A doesn't lead me to believe struct members could not be used as integer constants. – Theo d'Or Jan 22 '20 at 10:18
  • The linked question/answer applies to everything that is not a (compile-time) constant expression. A struct instance is not a compile-time entity, so it can't be a compile-time constant. The linked answers also address what you should do instead. – Sander De Dycker Jan 22 '20 at 10:49
  • 1
    You can very well modify the values of that... it's not a constant in any way. – Marco Bonelli Jan 22 '20 at 10:54
  • 1
    It doesn't matter if your variable is of struct type or not. A variable is simply not a constant expression. That's why they are called *variables* – Gerhardh Jan 22 '20 at 11:17
  • So an enum is not a variable? They can be used as integer constants, can't they? – Theo d'Or Jan 22 '20 at 11:40
  • 1
    enum *values* are compile-time. enum *variables* aren't. So, `enum EnumType { INT }; EnumType var = INT; switch (var) { case INT : break; }` is ok, but `enum EnumType { INT }; EnumType var = INT; switch (var) { case var : break; }` isn't. – Sander De Dycker Jan 22 '20 at 12:27
  • @SanderDeDycker Thank you for explaining `enum`. I think I understand the requirement for integer constants now, they must be guaranteed to be unchanging. Stating this now seems like stating the obvious, but I still got thrown by the struct. I thought "if it's initialized at compile time, it can be read as constant", but "can be" isn't good enough, it must be constant. – Theo d'Or Jan 22 '20 at 12:38
  • Sounds like you got it. Note there's also the concept of a run-time "constant" (ie. using `const`). This also can't be used as a compile-time constant, since it's [not *actually* guaranteed to be immutable](https://stackoverflow.com/questions/15576000/in-c-can-a-const-variable-be-modified-via-a-pointer). – Sander De Dycker Jan 22 '20 at 13:33

2 Answers2

0

switch-case statement is syntactical sugar of on-condition jump instruction. case label are converted into goto equivalent at compile time. In your case types is a struct variable and compiler will not able to deduce a equivalent label for it.

from [6.8.4.2 The switch statement]

The expression of each case label shall be an integer constant expression

TruthSeeker
  • 1,539
  • 11
  • 24
  • I take your answer as basically saying no, struct members cannot work as integer constants. If I've got that right, why is that so? After all, the struct is initialized at compile time. – Theo d'Or Jan 22 '20 at 10:20
  • yes, as struct just a user defined datatype. case label expects `integer const` such as `sizeof()` `enum`, `macro` etc. of which compiler can deduce the value. Even though struct variable is initialized compiler will not able to deuce it value. – TruthSeeker Jan 22 '20 at 10:29
  • The question asks whether initialized structure members may serve as constants, not whether case labels must be constants. This answer soes not answer the question. – Eric Postpischil Jan 22 '20 at 12:21
0

The same error is for example:

int a = 0;
int b = 0;
switch (b)
{
    case a:
...

It can be resolved to:

const int a = 0;
int b = 0;
switch (b)
{
    case a:
...

Currently I use same 'hiding of enum', to mimic 'modules' in C. I can't resolve it even if I define struct as const, or even static const.