Skip to content

UNITY_NORETURN redefines noreturn, uses stdnoreturn.h which can break compatibility with C23 and is being defined when unnecessary #742

@jmuntaner-smd

Description

@jmuntaner-smd

I have encountered some issues with the UNITY_NORETURN macro that I think that could be improved:

  • Compiling with a GNU_C compiler with a version between C11 and C17, makes it so the macro ends up including the header <stdnoreturn.h> which defines noreturn to _Noreturn. If an external header that is included after unity.h uses attribute (noreturn)), it will get replaced by attribute (_Noreturn)) which is not valid.
  • UNITY_NORETURN is only used if UNITY_EXCLUDE_SETJMP_H is not defined, but the macro is always being defined.
  • Starting from version C23, _Noreturn is deprecated and the attribute [[ noreturn ]] should be used

My approach would be something like the following code:

/* UNITY_NORETURN is only required if we have setjmp.h. */
#ifndef UNITY_EXCLUDE_SETJMP_H
  #ifndef UNITY_NORETURN
    #if defined(__cplusplus)
      #if __cplusplus >= 201103L
        #define UNITY_NORETURN [[ noreturn ]]
      #endif
    #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && __STDC_VERSION__ < 202311L
      /* _Noreturn keyword is used from C11 but deprecated in C23. */
      #if defined(_WIN32) && defined(_MSC_VER)
        /* We are using MSVC compiler on Windows platform. */
        /* Not all Windows SDKs supports <stdnoreturn.h>, but compiler can support C11: */
        /* https://devblogs.microsoft.com/cppblog/c11-and-c17-standard-support-arriving-in-msvc/ */
        /* Not sure, that Mingw compilers has Windows SDK headers at all. */
        #include <sdkddkver.h>
      #endif

      /* Using Windows SDK predefined macro for detecting supported SDK with MSVC compiler. */
      /* Mingw GCC should work without that fixes. */
      /* Based on: */
      /* https://docs.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt?view=msvc-170 */
      /* NTDDI_WIN10_FE is equal to Windows 10 SDK 2104 */
      #if defined(_MSC_VER) && ((!defined(NTDDI_WIN10_FE)) || WDK_NTDDI_VERSION < NTDDI_WIN10_FE)
        /* Based on tests and: */
        /* https://docs.microsoft.com/en-us/cpp/c-language/noreturn?view=msvc-170 */
        /* https://en.cppreference.com/w/c/language/_Noreturn */
        #define UNITY_NORETURN _Noreturn
      #else /* Using newer Windows SDK or not MSVC compiler */
        #if defined(__GNUC__)
          /* The header <stdnoreturn.h> collides with __attribute(noreturn)__ from GCC. */
          #define UNITY_NORETURN _Noreturn
        #else
          #include <stdnoreturn.h>
          #define UNITY_NORETURN noreturn
        #endif
      #endif
    #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
      /* Since C23, the keyword _Noreturn has been replaced by the attribute noreturn, based on: */
      /* https://en.cppreference.com/w/c/language/attributes/noreturn */
      #define UNITY_NORETURN [[ noreturn ]]
    #endif
  #endif
  #ifndef UNITY_NORETURN
    #define UNITY_NORETURN UNITY_FUNCTION_ATTR(__noreturn__)
  #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