Skip to content

Feature: C99 and C++11

Jacob Faibussowitsch requested to merge jacobf/2022-01-05/c99 into main

1999: the final frontier. These are the voyages of the ISO/IEC standard 9899:1999. Its twelve-year mission: to explore strange new keywords. To seek out new data types and new standard headers. To boldly go where no ANSI C compiler has gone before!

What this MR does:

  • Add petscompilerguard.h containing
#if defined(__cplusplus)
/*
 This is a 2-part problem:
 1. Intel compilers define __cplusplus to 1 instead of the C++ version (?????????????????)
 2. Intel cannot make their mind up on which of these gives the version of the compiler
*/
#  if defined(__INTEL_COMPILER)
#    define PETSC_INTEL_CXX_VERSION __INTEL_COMPILER
#  elif defined(__ICL)
#    define PETSC_INTEL_CXX_VERSION __ICL
#  elif defined(__ICC)
#    define PETSC_INTEL_CXX_VERSION __ICC
#  elif defined(__ECC)
#    define PETSC_INTEL_CXX_VERSION __ECC
#  endif
#  if defined(PETSC_INTEL_CXX_VERSION)
#    if PETSC_INTEL_CXX_VERSION < 1500 /* ICC/L V 15.0 */
#      error "PETSc requires an Intel Compiler of at least version 15 for C++11"
#    endif
#    undef PETSC_INTEL_CXX_VERSION /* cleanup */
#  elif __cplusplus < 201103L /* C++11 */
#    error "PETSc requires a C++ compiler that defines __cplusplus >= 201103L (C++11)"
#  endif
/*
 Visual Studio C compiler does not define __STDC__ unless it is in C89 mode, even though it
 may support an acceptable subset of C99. So it gets special treatment here.
*/
#elif defined(_MSC_VER)
#  if _MSC_VER < 1900
#    error "PETSc requires a Visual Studio C compiler that defines _MSC_VER >= 1900 (Visual Studio 2015)"
#  endif
#elif defined(__STDC__)
#  if defined(__STDC_VERSION__) /* __STDC_VERSION__ since C94 */
#    if (__STDC__ != 1) || (__STDC_VERSION__ < 199901L) /* C99 */
#      error "PETSc requires a C compiler that defines __STDC__ = 1 and __STDC__VERSION__ >= 199901L (C99)"
#    endif
#  else /* __STDC__VERSION__ */
#    error "PETSc requires a C compiler that defines __STDC__ = 1 and __STDC__VERSION__ >= 199901L (C99)"
#  endif
#endif

and #include it in all top-level headers (i.e. any that directly includes petscconf.h): petscerror.h, petscvec_kokkos.hpp, petscblaslapack.h, petscsystypes.h, petsc/mpiuni/mpi.h, petsc/mpiuni/mpiunifdef.h

  • Deprecate PETSC_INLINE (and its configure checks), inline is a standard keyword since C99 and C++11
  • Deprecate PETSC_STATIC_INLINE, its constituent parts are standard keywords since C99 and C++11
rg -l --no-stats PETSC_STATIC_INLINE | xargs sed -i 's/PETSC_STATIC_INLINE/static inline/g'
  • Remove PETSC_C_RESTRICT, restrict is a standard keyword since C99
  • include stdbool.h in petscsystypes.h
  • Make SETERRQ() variadic
    • Deprecate SETERRQ[1-9]() and replace with SETERRQ()
      rg -l --no-stats "(SETERRQ[1-9]+\()" | xargs sed -E -i "s/SETERRQ[1-9]+\(/SETERRQ\(/g"
  • Make SETERRMPI() variadic
  • Make SETERRABORT() variadic
  • Make PetscInfo() variadic
    • Deprecate PetscInfo[1-9]() and replace with PetscInfo()
      rg -l --no-stats "(PetscInfo[1-9]+\()" | xargs sed -E -i "s/PetscInfo[1-9]+\(/PetscInfo\(/g"
  • Enforce C++11 at configure-time
    • Remove PETSC_HAVE_CXX_DIALECT_CXX03
      • Bump minimum --with-cxx-dialect option to "11"
      • Remove self.minCxxDialectVersion = 11 in packages (as it is pointless)
    • Remove PETSC_HAVE_CXX_DIALECT_CXX11 checks in src (but keep the variable)
  • Add PetscDesignatedInitializer()
    • Apply it to Vec_Seq, Vec_MPI, and PetscRandom_*
  • Bring petscbt.h into the 21st century
  • Remove PETSC_CONSTEXPR, PETSC_NOEXCEPT, and PETSC_NOEXCEPT_ARG()
  • Replace if (<condition>) SETERRQ with PetscCheckFalse():
    rg -l --no-stats --pcre2 'if +\((?!.*PetscUnlikely).*\) *SETERRQ' | xargs perl -pi -e 's/if +\((?!.*PetscUnlikely)(.*)\) *SETERRQ\(/PetscCheckFalse($1,/g;'
  • Replace if (PetscUnlikely(<condition>)) SETERRQ with PetscCheckFalse()
    rg -l --no-stats --pcre2 'if +\((?!.*PetscUnlikelyDebug).*\) *SETERRQ' | xargs perl -pi -e 's/if +\((?!.*PetscUnlikelyDebug)(.*)\) *SETERRQ *\(/PetscCheckFalse($1,/g; s/(?<=PetscCheckFalse\()PetscUnlikely\(([^)(]*+(?:(?R)[^)(]*)*+)\)/$1/g'
  • Replace if (PetscUnlikelyDebug(<condition>)) SETERRQ with PetscAssertFalse()
    rg -l --no-stats 'if +\(.*\) *SETERRQ' | xargs perl -pi -e 's/if +\(PetscUnlikelyDebug\(([^)(]*+(?:(?R)[^)(]*)*+)\)(.*)\) *SETERRQ *\(/PetscAssertFalse($1,/g'
  • Make PetscStackCallStandard() variadic
    rg -l --no-stats "PetscStackCallStandard" | xargs perl -pi -e 's/(?<=PetscStackCallStandard\()(.*?),\((.*)\)\)/$1,$2)/g'

TODO:

  • Update docs
  • [Maybe] Make PetscMalloc() variadic
  • [Maybe] Make PetscFree() variadic
  • [Maybe] Make PetscCalloc() variadic
  • Replace PetscBool with bool

Needs macro header from !4592 (merged)

Edited by Jacob Faibussowitsch

Merge request reports