Skip to content

Commit

Permalink
Do not define AVIF_ENABLE_NODISCARD for avif.h
Browse files Browse the repository at this point in the history
Make the AVIF_ENABLE_NODISCARD cmake option require C23 so that avif.h
can define the AVIF_NODISCARD macro as [[nodiscard]] without checking
the AVIF_ENABLE_NODISCARD macro. This requires changing avif.h to test
__STDC_VERSION__ >= 202000L, which is the value of __STDC_VERSION__ in
recent versions of GCC and Clang when -std=c2x or -std=gnu2x is
specified.

In general avif.h should only test compiler predefined macros. The only
exception is AVIF_DLL (ignoring the experimental feature macros.)

Fix #2352.
  • Loading branch information
wantehchang authored Aug 2, 2024
1 parent 39cf485 commit 93b4ad4
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 20 deletions.
32 changes: 14 additions & 18 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,19 @@ include(FetchContent)
include(FindPkgConfig)
include(AvifExternalProjectUtils)

option(AVIF_ENABLE_NODISCARD "Add [[nodiscard]] to some functions. CMake must be at least 3.21 to force C23." OFF)

# Set C99 as the default
set(CMAKE_C_STANDARD 99)
if(AVIF_ENABLE_NODISCARD)
# [[nodiscard]] requires C23.
if(CMAKE_VERSION VERSION_LESS 3.21.0)
message(FATAL_ERROR "CMake must be at least 3.21 to force C23, bailing out")
endif()
set(CMAKE_C_STANDARD 23)
set(CMAKE_C_STANDARD_REQUIRED ON)
else()
set(CMAKE_C_STANDARD 99)
endif()

# SOVERSION scheme: MAJOR.MINOR.PATCH
# If there was an incompatible interface change:
Expand All @@ -52,7 +63,6 @@ set(LIBRARY_SOVERSION ${LIBRARY_VERSION_MAJOR})
option(BUILD_SHARED_LIBS "Build shared avif library" ON)

option(AVIF_ENABLE_WERROR "Treat all compiler warnings as errors" OFF)
option(AVIF_ENABLE_NODISCARD "Add [[nodiscard]] to some functions. CMake must be at least 3.21 to force C23" OFF)

option(AVIF_ENABLE_EXPERIMENTAL_YCGCO_R "Enable experimental YCgCo-R matrix code" OFF)
option(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP
Expand Down Expand Up @@ -334,22 +344,6 @@ endif()

target_link_libraries(avif_obj PRIVATE avif_enable_warnings)

if(AVIF_ENABLE_NODISCARD)
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.21.0)
set(CMAKE_C_STANDARD 23)
set_property(TARGET avif_obj PROPERTY C_STANDARD 23)
else()
unset(CMAKE_C_STANDARD)
set_property(TARGET avif_obj PROPERTY C_STANDARD)
if(CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID MATCHES "GNU")
target_compile_options(avif_obj PUBLIC $<BUILD_INTERFACE:$<$<COMPILE_LANGUAGE:C>:-std=gnu2x>>)
elseif(CMAKE_C_COMPILER_ID MATCHES "MSVC")
target_compile_options(avif_obj PUBLIC $<BUILD_INTERFACE:$<$<COMPILE_LANGUAGE:C>:/std:clatest>>)
endif()
endif()
target_compile_definitions(avif_obj PUBLIC $<BUILD_INTERFACE:AVIF_ENABLE_NODISCARD=1>)
endif()

if(AVIF_ENABLE_COVERAGE)
if(CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID MATCHES "GNU")
message(STATUS "libavif: Enabling coverage for Clang")
Expand Down Expand Up @@ -592,7 +586,9 @@ if(AVIF_LIB_USE_CXX OR (AVIF_BUILD_APPS AND AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP) O
)
enable_language(CXX)
if(AVIF_ENABLE_NODISCARD)
# [[nodiscard]] requires C++17.
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
else()
set(CMAKE_CXX_STANDARD 14)
endif()
Expand Down
10 changes: 8 additions & 2 deletions include/avif/avif.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,14 @@ extern "C" {
#define AVIF_API
#endif // defined(AVIF_DLL)

#if defined(AVIF_ENABLE_NODISCARD) || (defined(__cplusplus) && __cplusplus >= 201703L) || \
(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L)
// [[nodiscard]] requires C++17 and C23.
//
// If the -std=c2x or -std=gnu2x option is specified, __STDC_VERSION__ is
// * 202000L in GCC 13.2.0, Clang 16.0.6, and Apple Clang 15.0.0; or
// * 202311L in Clang 19.0.0git.
// If the /std:clatest option is specified, __STDC_VERSION__ is
// * 202312L in Microsoft Visual Studio 17.10.5.
#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L)
#define AVIF_NODISCARD [[nodiscard]]
#else
// Starting with 3.9, clang allows defining the warn_unused_result attribute for enums.
Expand Down

0 comments on commit 93b4ad4

Please sign in to comment.