Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to use a constant array with constant index as switch case label in C?

I have some constant values and arrays defining their labels and their hash codes. For example,

#define LABEL_A 0 //or const int LABEL_A = 0;
#define LABEL_B 1
#define LABEL_C 2
#define LABEL_D 3

const char *VALUE[] = {"LABEL_A", "LABEL_B", "LABEL_C", "LABEL_D"};
const int VALUE_HASH[] = {67490, 67491, 67493, 67459);

At run-time, these labels can come in any order and needs to be parsed accordingly. I am using switch case for this purpose. This code is generating error at compile time "constant expression is required.

function(const char* LabelAtRuntime){
  int i = getHashCode(LabelAtRuntime);
  switch(i){
    case VALUE_HASH[LABEL_A]: //line giving compile time error
      break;
    default:
      break;
}

But, when I provide actual constants, it works. This code works well.

function(const char* LabelAtRuntime){
  int i = getHashCode(LabelAtRuntime);
  switch(i){
    case 67490: //line not giving compile time error
      break;
    default:
      break;
}
  1. I am unable to understand, why is it happening? Both my array and its index are constants, then isn't it equivalent to a constant literal?
  2. Is there any other way by which I can provide my constants in required manner?

I am using constants in this manner to provide better code semantics, readability and reusability. Please do not provide if-else based solution. In above example, there are only 4 labels, but in practical, there could be 100.

like image 250
Amber Beriwal Avatar asked Mar 06 '17 09:03

Amber Beriwal


People also ask

How can constants be used when working with arrays?

You can create an array constant and you can give it a name that can then be used in your formulas. Array constants are a list of values that can be used as arguments in your array formulas. Arrays can be either 1-dimensional or 2-dimensional depending on the number of rows and columns.

What is constant array in C?

it's a constant array of integers i.e. the address which z points to is always constant and can never change, but the elements of z can change.

Can a constant be an array PHP?

Apparently, constants can't hold arrays.

What is the correct way to declare a constant array in JavaScript?

To create a const array in JavaScript we need to write const before the array name. The individual array elements can be reassigned but not the whole array.


1 Answers

In C++, this compiles:

#include <stdio.h>
#include <stdlib.h>

constexpr int x[] = { 42, 43 };

int main(int argc, char **argv)
{
    switch(atoi(argv[1]))
    {
        case x[0]: puts("forty_two");
                   break;
        case x[1]: puts("forty_three");
    }
    return 0;
}

So constexpr on the array appears to be the solution in modern C++. (Note: the question was originally tagged C++ and C)

It's impossible in C if you want to keep the array. Switch cases require an integer constant, but once you put an integer constant in a variable, it becomes a runtime entity (even if it's declared const). What you could do is replace the in-memory array with just a bunch of direct defines and possibly have a macro that looks up macros using other macros (if you want to keep your form of the code):

#define LABEL_A 0
#define LABEL_B 1
#define LABEL_C 2
#define LABEL_D 2

#define VALUE_HASH__0 67490
#define VALUE_HASH__2 67491
#define VALUE_HASH__3 67491
#define VALUE_HASH__4 64759

//append what Index expands to to VALUE_HASH__
#define HASH_LOOKUP(Index) MC_cat(VALUE_HASH__,Index) 
#define MC_cat_(X,Y) X##Y
#define MC_cat(X,Y) MC_cat_(X,Y)

function(const char* LabelAtRuntime){
  int i = getHashCode(LabelAtRuntime);
  switch(i){
    case HASH_LOOKUP(LABEL_A)
      break;
    default:
      break;
}
like image 159
PSkocik Avatar answered Oct 26 '22 10:10

PSkocik