Skip to content

suspicious static checks for sizeof(nk_bool) #849

@sleeptightAnsiC

Description

@sleeptightAnsiC

If you try to provide your own NK_BOOL - either by defining it to C99 _Bool, C++ bool, or some small integer type like int8_t - there will be two static asserts that fail and prevent you to do so.

repro:

$ git clone https://github.com/Immediate-Mode-UI/Nuklear.git
$ cd Nuklear/
$ cat <<'EOF' >testcase.c
    #define NK_BOOL _Bool                                                                                                                                                                                                                                      
    #define NK_IMPLEMENTATION                                                                                                                                                                                                                                  
    #include "./nuklear.h"                                                                                                                                                                                                                                     
    int main(void) { return 0; }                                                                                                                                                                                                                               
EOF
$ cc testcase.c
result (CLICK ME)

In file included from testcase.c:3:
./nuklear.h:302:61: error: size of array ‘_dummy_array449’ is negative
  302 |   #define NK_STATIC_ASSERT(exp) typedef char NK_UNIQUE_NAME(_dummy_array)[(exp)?1:-1]
      |                                                             ^~~~~~~~~~~~
./nuklear.h:291:46: note: in definition of macro ‘NK_STRING_JOIN_IMMEDIATE’
  291 | #define NK_STRING_JOIN_IMMEDIATE(arg1, arg2) arg1 ## arg2
      |                                              ^~~~
./nuklear.h:293:36: note: in expansion of macro ‘NK_STRING_JOIN_DELAY’
  293 | #define NK_STRING_JOIN(arg1, arg2) NK_STRING_JOIN_DELAY(arg1, arg2)
      |                                    ^~~~~~~~~~~~~~~~~~~~
./nuklear.h:298:32: note: in expansion of macro ‘NK_STRING_JOIN’
  298 |   #define NK_UNIQUE_NAME(name) NK_STRING_JOIN(name,__LINE__)
      |                                ^~~~~~~~~~~~~~
./nuklear.h:302:46: note: in expansion of macro ‘NK_UNIQUE_NAME’
  302 |   #define NK_STATIC_ASSERT(exp) typedef char NK_UNIQUE_NAME(_dummy_array)[(exp)?1:-1]
      |                                              ^~~~~~~~~~~~~~
./nuklear.h:449:1: note: in expansion of macro ‘NK_STATIC_ASSERT’
  449 | NK_STATIC_ASSERT(sizeof(nk_bool) >= 2);
      | ^~~~~~~~~~~~~~~~
./nuklear.h:302:61: error: size of array ‘_dummy_array6128’ is negative
  302 |   #define NK_STATIC_ASSERT(exp) typedef char NK_UNIQUE_NAME(_dummy_array)[(exp)?1:-1]
      |                                                             ^~~~~~~~~~~~
./nuklear.h:291:46: note: in definition of macro ‘NK_STRING_JOIN_IMMEDIATE’
  291 | #define NK_STRING_JOIN_IMMEDIATE(arg1, arg2) arg1 ## arg2
      |                                              ^~~~
./nuklear.h:293:36: note: in expansion of macro ‘NK_STRING_JOIN_DELAY’
  293 | #define NK_STRING_JOIN(arg1, arg2) NK_STRING_JOIN_DELAY(arg1, arg2)
      |                                    ^~~~~~~~~~~~~~~~~~~~
./nuklear.h:298:32: note: in expansion of macro ‘NK_STRING_JOIN’
  298 |   #define NK_UNIQUE_NAME(name) NK_STRING_JOIN(name,__LINE__)
      |                                ^~~~~~~~~~~~~~
./nuklear.h:302:46: note: in expansion of macro ‘NK_UNIQUE_NAME’
  302 |   #define NK_STATIC_ASSERT(exp) typedef char NK_UNIQUE_NAME(_dummy_array)[(exp)?1:-1]
      |                                              ^~~~~~~~~~~~~~
./nuklear.h:6128:1: note: in expansion of macro ‘NK_STATIC_ASSERT’
 6128 | NK_STATIC_ASSERT(sizeof(nk_bool) == 4);
      | ^~~~~~~~~~~~~~~~

Those checks do not make much sense to me. Not only they differ from each other (1st one is >=2 and the 2nd one is ==4) but also they're conditional when pulling <stdbool> (which implies that NK_BOOL can be smaller than 2). Also, the check for sizeof(nk_bool) == sizeof(bool) seems irrelevant, because nk_bool is always the same as bool in this specific case.

#ifdef NK_INCLUDE_STANDARD_BOOL
NK_STATIC_ASSERT(sizeof(nk_bool) == sizeof(bool));
#else
NK_STATIC_ASSERT(sizeof(nk_bool) == 4);
#endif

Nuklear/src/nuklear.h

Lines 223 to 227 in fcd64f8

#ifdef NK_INCLUDE_STANDARD_BOOL
NK_STATIC_ASSERT(sizeof(nk_bool) == sizeof(bool));
#else
NK_STATIC_ASSERT(sizeof(nk_bool) >= 2);
#endif

Some reasoning why those assert even exist could be [snippet below] but I don't believe this justifies anything.

Nuklear/src/nuklear.h

Lines 187 to 194 in fcd64f8

#ifndef NK_BOOL
#ifdef NK_INCLUDE_STANDARD_BOOL
#include <stdbool.h>
#define NK_BOOL bool
#else
#define NK_BOOL int /**< could be char, use int for drop-in replacement backwards compatibility */
#endif
#endif

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions