1

When you declare a enum, the constant values of the enumerator-list automatically increment. E.g.

typedef enum{
 TEST0 = 0,
 TEST_X, // automatically will be 1
 TEST_Y, // ...will be 2
...
}test_t;

Is there a way to make the enumeration constants decrease instead of increase the values? For example with a attribute directive before the type definition or any other solution?

So my desired behavioral:

typedef enum{
 TEST0 = 0,
 TEST_X, // want to be -1
 TEST_Y, // want to be -2
...
}test_t;

The only trick/workaround that comes to my mind would be:

 typedef enum{
 TEST_LOWEST = -2000,
 TEST_X, //-1999
 TEST_Y, //-1998
...
 TEST0 = 0,
}test_t;

I didn't find an attribute, but maybe there's another solution. But the workaround described above indeed works, too.

  • 1
    There's no way to do this in standard C. Your workaround is probably your best chance. – pmacfarlane Jan 26 '23 at 11:06
  • 1
    Why do you need this? Primary reason for automatic incrementing is to generate array indexes or automatic count as last element. Neither of these apply to negative numbers. If your only reason is to save typing, it's just better to just use explicit number assignment. – user694733 Jan 26 '23 at 11:21
  • You could declare your enum in reverse order. A la: TEST_Y, TEST_X, TEST_0. – SafelyFast Jan 26 '23 at 12:32
  • Hi user694733. I need it for a project which has mixed and incomplete error handling. I wanted to keep downwards compatibility (many functions check the return value for an error <0. Those functions just return -1 or other "random" negative values). But I also want to extend the code and step by step refactor the old one to more readability and maintainable error handling – EmbeddedAlex Jan 26 '23 at 12:35
  • 2
    If backwards compatibility is a factor, then you should definitely use explicit numbering. With any kind of trick code you're just asking for trouble. – user694733 Jan 26 '23 at 12:41
  • `TEST_X = TEST0 - 1,` might be one approach. Make the dependency between items explicit. – Lundin Jan 26 '23 at 13:04

1 Answers1

4

There is no way to do it in pure C. I am not aware of any compiler extension allowing it. As a workaround, you could use a line number accessible via __LINE__ macro and subtract it from the start to achieve desired behavior.

#include <stdio.h>

enum {
    START = 42 + 1 + __LINE__,
    ENUM0 = START - __LINE__,
    ENUM1 = START - __LINE__,
    ENUM2 = START - __LINE__,
};

int main(void) {
    printf("%d %d %d", ENUM0, ENUM1, ENUM2);
}

prints:

42 41 40

The safer alternative could use __COUNTER__ macro available in GCC/CLANG. This macro returns an integer incremented whenever the __COUNTER__ macro is expanded.

tstanisl
  • 13,520
  • 2
  • 25
  • 40
  • I like the __LINE__ /__COUNTER__ solution. The only problem I have with it that I'm to lazy to always copy paste this phrase for new enums. I think I stay with my workaround, having the lowest negative value necessary as initializer. – EmbeddedAlex Jan 26 '23 at 12:37
  • Imagine you suddenly decide to document the enum items and suddenly all your code is failing :D – Victor Jan 27 '23 at 09:36
  • @Victor, presence of `__LINE__` macro makes it evident that playing with the line ordering may bring problems. Any comments can be placed after comma in `//` comment. Finally, one can always use `__COUNTER__` macro. – tstanisl Jan 27 '23 at 10:19
  • 1
    @tstanisl I agree, but I found it funny and thought to share :) – Victor Jan 27 '23 at 11:48
  • 1
    @Victor, I agree :). – tstanisl Jan 27 '23 at 12:17