Hibou57
Hibou57

Reputation: 7170

Local static constants in Vala: possible?

The land

Vala provides enumerations. But these cannot be defined locally to a sub‑program. Constants can be defined locally to a sub‑program, but seems to not be treated as static expressions (pseudo constants so).

The case

I have some sub‑programs implemented as state machines built with switch statements. I use some switch (state) { … } and want to use some constant for the case statements, as in case initial_state: { … }. This is recommended I believe, as it is more readable and maintainable than using literal constants as in case 0: { … }.

I tried to defined these constants inside the sub‑program, using declarations like const int initial_state = 0;. But Vala complains at each case statements. I tried to define an enumerations for the states, as in enum State { initial_state, … };, but Vala reject this as a syntax error and seems to only allows enumerations declarations outside of sub‑programs.

So far, I have to either define all states enumerations as external to the sub‑programs, or else to define constants inside the sub‑programs, but then have to use if constructs instead of switch constructs, as it's OK for the if condition expression, to not be static.

The question

Do Vala allows to define static constants (of a scalar type) locally to a sub‑program in some way?

Upvotes: 2

Views: 691

Answers (1)

nemequ
nemequ

Reputation: 17492

This is actually an error from gcc, not valac. Using this example:

private void foo (int val) {
  const int one = 1;
  const int two = 2;
  const int three = 3;

  switch ( val ) {
    case one:
      GLib.debug ("One");
      break;
    case two:
      GLib.debug ("One");
      break;
    case three:
      GLib.debug ("Three");
      break;
    default:
      GLib.debug (val.to_string ());
      break;
  }
}

valac will generate:

void foo (gint val) {
    static const gint one = 1;
    static const gint two = 2;
    static const gint three = 3;
    gint _tmp0_;
    _tmp0_ = val;
    switch (_tmp0_) {
        case one:
        {
            g_debug ("t.vala:8: One");
            break;
        }
        case two:
        {
            g_debug ("t.vala:11: One");
            break;
        }
        case three:
        {
            g_debug ("t.vala:14: Three");
            break;
        }
        default:
        {
            gint _tmp1_;
            gchar* _tmp2_ = NULL;
            gchar* _tmp3_;
            _tmp1_ = val;
            _tmp2_ = g_strdup_printf ("%i", _tmp1_);
            _tmp3_ = _tmp2_;
            g_debug ("t.vala:17: %s", _tmp3_);
            _g_free0 (_tmp3_);
            break;
        }
    }
}

gcc will say something like:

t.vala.c:25:3: error: case label does not reduce to an integer constant
t.vala.c:30:3: error: case label does not reduce to an integer constant
t.vala.c:35:3: error: case label does not reduce to an integer constant

Interestingly, clang is fine with it (valac --cc=clang ..., if you want to play with it).

Upvotes: 3

Related Questions