1

C11, 6.2.5 Types, 18:

Integer and floating types are collectively called arithmetic types.

C11, 6.2.5 Types, 16:

An enumeration comprises a set of named integer constant values. Each distinct enumeration constitutes a different enumerated type.

C11, 6.5.5 Multiplicative operators, Constraints, 2 (emphasis added):

Each of the operands shall have arithmetic type.

Sample code:

enum E { a };
int f(enum E x)
{
        return x * x;
}

Invocations:

$ gcc t0.c -std=c11 -pedantic -Wall -Wextra -c
<nothing>

$ clang t0.c -std=c11 -pedantic -Wall -Wextra -c
<nothing>

$ icc t0.c -std=c11 -pedantic -Wall -Wextra -c
<nothing>

$ cl t235.c /std:c11 /Za /c
<nothing>

Question: Does x * x (and similar) lead to constraint violation?

As I understand, the operand x has enumerated type, not arithmetic type.

pmor
  • 5,392
  • 4
  • 17
  • 36

2 Answers2

3

Enumerated types are integer types, which are arithmetic types. There is no constraint violation.

From n1548: 6.2.5.17

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

"Integer types" are arithmetic types, as you noted.

Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
1

I have not understood what constraint you are referring.

According to the C Standard (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.

The operator * is defined for integer types because they are a part of arithmetic types.

18 Integer and floating types are collectively called arithmetic types.

Only you need to bear in mind that there is a difference between applying the operator to objects of an enumeration type and to its enumerators. Enumerators in C have always the type int while the compatible integer type of enumerations is implementation defined.

Consider the following demonstration program.

#include <stdio.h>

int main(void) 
{
    enum E { a = 1 };
    
    enum E e = a;
    
    printf( "e * -1 < 0 is %d\n", e * -1 < 0);
    printf( "a * -1 < 0 is %d\n", a * -1 < 0);

    return 0;
}

Its output can be

e * -1 < 0 is 0
a * -1 < 0 is 1

Opposite to C in C++ enumerations are not integral types however unscoped enumerations can be promoted to integral types.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Thanks for the demo, interesting. Indeed, per implementation an enumerated type can be compatible with, for example, an unsigned integer type. – pmor Feb 05 '22 at 20:30
  • Re: "what constraint you are referring": "Each of the operands shall have arithmetic type" (C11, 6.5.5 Multiplicative operators, Constraints, 2). – pmor Feb 05 '22 at 20:31
  • @pmor You are right. As the enumerators are positive numbers the enumeration can have the type unsigned int. So due to the arithmetic usual conversions the signed int type sill be converted to the unsigned int type. – Vlad from Moscow Feb 05 '22 at 21:33