Having 2 strange warnings during auto generation enum + string items...
EnumItems.h (2 times included header to build enum and string array + possibility to have multiple enums and single boilerplate)
#ifdef ENUM_ONCE_INCLUDED
    #undef ENUM_NUMBERED
    #undef ENUM_ITEM
    #define ENUM_NUMBERED(i, n) *(new TemporaryItem( #i, n ))
    #define ENUM_ITEM(i) *(new TemporaryItem( #i ))
  #undef ENUM_ONCE_INCLUDED
#else
    #define ENUM_NUMBERED(i, n) i = n
    #define ENUM_ITEM(i) i
  #define ENUM_ONCE_INCLUDED
#endif // ENUM_ONCE_INCLUDED
#ifndef ENUM_ITEMS
#error Undefined ENUM_ITEMS # !
#elif ENUM_ITEMS == 1
{
    ENUM_NUMBERED(E_LOREM, 0),
    ENUM_NUMBERED(E_IPSUM, 1),
    ENUM_ITEM(E_DOLOR),
    ENUM_NUMBERED(E_SIT, 20)
}
#endif // ENUM_ITEMS
#ifdef ENUM_ONCE_INCLUDED
    ;
    #if defined(__ICCARM__) && defined(DEBUG)
        #pragma diag_suppress=Pa105
    #endif
#else
    ,_once = TemporaryItem::PostProcess(states, sizeof(states));static_cast<void>(_once);
    #if defined(__ICCARM__) && defined(DEBUG)
        #pragma diag_default=Pa105
    #endif
#endif // ENUM_ONCE_INCLUDED
*.cpp(s)
#define ENUM_ITEMS 1
namespace
{
    enum second_t
    #include "EnumItems.h" // standard enum items - 1st include
    // F12 jumps to particular item in header
}
static const char *states[21] =
#include "EnumItems.h" // struct TemporaryItem* - 2nd include
Sigle expected a declaration with additional brackets in EnumItems.h (for multiple enums)
- or lot of this declaration has no storage without in Visual Studio Error List only
and Remark[Pa105]: this directive is inside an active namespace scope ## in IAR, but this is true in most cases unfortunately.
Is it possible to remove them somehow (except supress in IAR) ?
Or is there any similar and better way how to write enum + string counterparts without need to compare and synchronize their separate instances again and again ?
Mind final target is old-fashioned IAR EC++ compiler.
It is also unlikely impossible to use names for ENUM_ITEMS definitions without hard to read breakneck tricks.
Polymorphic struct/class used to check & store preprocessor generated definitions and rewrite them by string arrays.
struct TemporaryItem {
    const char *name; int pos;
    TemporaryItem(const char *n) { name = n; pos = INT_MIN; /* auto-generated */ }
    TemporaryItem(const char *n, int p) { name = n; pos = p; }
    static char PostProcess(const char **process, size_t size) {
        size /= sizeof(char *); // array size
        TemporaryItem **source = new TemporaryItem*[size];
        memcpy(source, process, sizeof(TemporaryItem*) * size); // copy definitions
        memset(process, 0, sizeof(TemporaryItem *) * size); // reset final range
        int stLogicNumber = source[0]->pos;
        if (stLogicNumber == INT_MIN) stLogicNumber = 0; // no logic shift
        int finalPos = 0; // default item destination
        for (size_t i = 0; i < size; i++) {
            TemporaryItem *current = source[i];
            if (current == NULL) break; // no more defined
            int defPos = current->pos;
            if (defPos == INT_MIN) defPos = finalPos; // auto-generated
            else if (stLogicNumber < 0)
                    defPos -= stLogicNumber; // move forward by 1st logic value
            if (defPos >= finalPos && static_cast<unsigned>(defPos) < size)
                finalPos = defPos; // set valid destination
            else __debugbreak(); // block backward && out of bounds
            process[finalPos] = current->name;
            delete current; // remove processed definition
            finalPos++;
        }
        delete[] source; // remove temp array
        return 0;
    }
    operator const char *() // collect TemporaryItem-s definitions in destination array
    { return reinterpret_cast<const char *>(this); }
};
1st version having nice get/set operators also here easily map c++ enums to strings, but enum items are useless mixed by preprocessor to single line there.
