utest.h icon indicating copy to clipboard operation
utest.h copied to clipboard

Compilation warning when comparing enum literal and enum variable

Open Roysten opened this issue 1 year ago • 3 comments

Reproducer:

#include "utest.h"

enum My_enum {
	MY_ENUM_A,
	MY_ENUM_B,
	MY_ENUM_C,
};

UTEST(Utest, sign_compare)
{
	enum My_enum e = MY_ENUM_A;
	ASSERT_EQ(MY_ENUM_A, e);
}

UTEST_MAIN()

Compilation:

gcc -std=gnu11 -Wall -Wextra -pedantic src-test/main.c

In file included from src-test/main.c:1:
src-test/main.c: In function ‘utest_run_Utest_sign_compare’:
src-test/utest.h:828:42: warning: comparison of integer expressions of different signedness: ‘int’ and ‘unsigned int’ [-Wsign-compare]
  828 | #define ASSERT_EQ(x, y) UTEST_COND(x, y, ==, "", 1)
      |                                          ^~
src-test/utest.h:783:18: note: in definition of macro ‘UTEST_COND’
  783 |     if (!((xEval)cond(yEval))) {                                               \
      |                  ^~~~
src-test/main.c:17:9: note: in expansion of macro ‘ASSERT_EQ’
   17 |         ASSERT_EQ(MY_ENUM_A, e);
      |         ^~~~~~~~~

This was surprising to me. Note that an explicit cast of the variable e to int compiles without warning. GCC version 12.2.0.

Roysten avatar Nov 21 '24 19:11 Roysten

Is there any news about this ?

baronleonardo avatar Jan 28 '25 12:01 baronleonardo

Happy to accept a PR.

sheredom avatar Jan 28 '25 12:01 sheredom

I would explain the cause if someone has an idea how could we solve this

the problem is how optimization from gcc/clang do for enum itself and __auto_type for optimization the type of enum could be larger or smaller and __auto_type will deduce that from the compiler this happens because the enum I used and probably the same for Roysten does not had any negative numbers so it has been optimized to unsigned int.

solutions:

  • cast enum to int
  • add U suffix to the number you want to compare with enums
  • you could compile with -fno-short-enums this will stop this behavior
  • from this library side, we could use this around UTEST_COND
#pragma GCC push_options
#pragma GCC optimize ("-fno-short-enums")

// code ...

#pragma GCC pop_options

baronleonardo avatar Jan 28 '25 12:01 baronleonardo