ccompiler-errorspost-incrementpostfix-operatorenumerated-types

for loop through enumerated type in C raising compilation error


I have a code that defines a simple enumerated type, then loop through it to print the corresponding syllable.

#include <stdio.h>

typedef enum syllable
{
  Do=1, Re=2, Mi=3, Fa=4, So=5, La=6, Ti=7
} Syllable;

void Sound(Syllable sy)
{
  switch (sy)
  {
    case Do:
      puts("Do"); return;
    case Re:
      puts("Re"); return;
    case Mi:
      puts("Mi"); return;
    case Fa:
      puts("Fa"); return;
    case So:
      puts("So"); return;
    case La:
      puts("La"); return;
    case Ti:
      puts("Ti"); return;
  }
  puts("Sing together~");
}

int main(void)
{
  Syllable tone;
  for (tone=Do; tone<Ti; tone++)
    Sound(tone);
  
  return 0;
}

However, this code is raising error no 'operator++(int)' declared for postfix '++' [-fpermissive] on compilation at line tone++. What am I doing wrong here, and how can I fix it such that I can loop through Syllable correctly?


Solution

  • It seems you are compiling your code as a C++ code.

    From the C++14 Standard (5.2.6 Increment and decrement)

    1 The value of a postfix ++ expression is the value of its operand. [ Note: the value obtained is a copy of the original value — end note ] The operand shall be a modifiable lvalue. The type of the operand shall be an arithmetic type or a pointer to a complete object type.

    and (3.9.1 Fundamental types)

    7 Types bool, char, char16_t, char32_t, wchar_t, and the signed and unsigned integer types are collectively called integral types.

    and

    8 There are three floating point types: float, double, and long double. The type double provides at least as much precision as float, and the type long double provides at least as much precision as double. The set of values of the type float is a subset of the set of values of the type double; the set of values of the type double is a subset of the set of values of the type long double. The value representation of floating-point types is implementation-defined. Integral and floating types are collectively called arithmetic types. Specializations of the standard template std::numeric_limits (18.3) shall specify the maximum and minimum values of each arithmetic type for an implementation

    As you can see enumerations are not included in the arithmetic types in C++. So the postfix increment operator for enumerations is not defined in C++.

    On the other hand, in C (The C Standard (6.5.2.4 Postfix increment and decrement operators)

    Constraints

    1 The operand of the postfix increment or decrement operator shall have atomic, qualified, or unqualified real or pointer type, and shall be a modifiable lvalue.

    and (6.2.5 Types)

    17 The type char, the signed and unsigned integer types, and the enumerated types are collectively called integer types. The integer and real floating types are collectively called real types.

    In C enumerations are included in the family of integer types and correspondingly in the family of real types for which the postfix increment operators is defined.

    So compile your code as a C code.

    In C++ you need explicitly to overload the postfix increment operator as a user-defined function something like

    Syllable operator ++( Syllable &e, int )
    {
        Syllable tmp = e == Ti ? Do : static_cast<Syllable>( e  + 1 );
    
        e = e == Ti ? Do : static_cast<Syllable>( e + 1 );
    
        return tmp;
    }