0

I want to print the value of an enumeration as a #warning or as a #pragma message. I use typedef enum instead of #define'ing values, as it makes editing easier and allows for typing function parameters and return values.

Reason for printing: The enum's constant max value must not exceed a certain value, however I can't check the value directly in the code, as its values are auto incremented: typedef enum {a, b, ... az } mytype_t;. In this example, az must be smaller than [any u_int].

I have tried to stringify the value according to this post, however it works only for #define'd values. I tried variations on the enum value, but I could not get the actual value to print, only its name.

Is there a way to print an enum value (or also a const variable) when compiling? Thanks.

EDIT: I use Microchips XC8 compiler (8 bit) and C99.

earthling
  • 620
  • 6
  • 20
  • You can't print an `enum` value because it is evaluated **after preprocessing**. The value is simply unavailable at `#warning` and `#pragma message` time. – Frankie_C Feb 11 '20 at 11:15
  • Use a `_Static_assert`. It will not print the value but will provide the test you want. – Eric Postpischil Feb 11 '20 at 11:31
  • What compiler? `#warning` isn't standard C, `#pragma X` is compiler-specific. – Lundin Feb 11 '20 at 12:05
  • Also what do you mean with "The enum value must not exceed a certain value", do you mean the enum variable's run-time value or the enumeration constant's value? – Lundin Feb 11 '20 at 12:09
  • @Frankie_C: makes sense now! @EricPostpischil: Thank you! I found something, that works for me. Not that pretty but does the job. @ Lundin: I forgot to specify. I use Microchips XC8 (8bit compiler) with C99, I will edit my post and add this information; I mean the `enum`'s constant value. It is a address list for the eeprom, which is 256 bytes large. – earthling Feb 11 '20 at 13:13
  • @RobertSsupportsMonicaCellio: typedef enum{green, red} color_t; void paint (color_t color) { // some code } – earthling Feb 11 '20 at 13:19

2 Answers2

1

The C standard does not provide for a way to report the values of enumeration constants in preprocessor macros or other compile-time methods. However, it is possible to test that the value is within a desired range.

As of C 2011, you can use _Static_assert to test enumeration constants:

enum { a, b, c, d, e };

_Static_assert(e <= 3, "Enumeration constant exceeds 3.");

Before C 2011, you can kludge tests in various ways, such as:

enum { a, b, c, d, e };

int FailIfSizeMismatches[1];      // Define array with good size.
int FailIfSizeMismatches[e <= 3]; // Define with conflicting size if test fails.

(In C++, replace _Static_assert with static_assert.)

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • Thank you, Eric. As I mentioned above (too late :) ), I use C 99. However I found a solution using your keywords: `#define STATIC_ASSERT(COND,MSG) typedef char static_assertion_##MSG[(!!(COND))*2-1]`. The compiler output ain't pretty, but it does not really matter, as it is only shown on error. BR – earthling Feb 11 '20 at 13:32
  • I also tried this method. However I did not like it as much as the other, because I either have to declare two arrays and not have a "pretty" ASSERT(x) in my code. `#define ASSERT do {your 2nd example} while(0)` will also only work in functions, not headers. However I have a solution for your issue, as written in my linked post. A ternary query that returns -1 on fail: `#define STATIC_ASSERT(COND,MSG) typedef char static_assertion_##MSG[(COND)?1:-1]` – earthling Feb 11 '20 at 14:28
0

As the comment Frankie_C written, you have to classify preprocessing and processing. enum is evaluated after preprocessing while #define, #pragma, #warning is evaluated on preprocessing

Sol1
  • 1
  • 1