Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleans up hsize_t and haddr_t size guessing #709

Merged
merged 2 commits into from
Jun 2, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 44 additions & 127 deletions src/H5public.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,14 @@ typedef int herr_t;
typedef bool hbool_t;
typedef int htri_t;

/* Define the ssize_t type if it not is defined */
/* The signed version of size_t
*
* ssize_t is POSIX and not defined in any C standard. It's used in some
* public HDF5 API calls so this work-around will define it if it's not
* present.
*
* Use of ssize_t should be discouraged in new code.
*/
Copy link
Member Author

@derobins derobins May 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intentionally not a Doxygen comment since this is a work-around vs a new HDF5 type. ssize_t is defined pretty much everywhere now, but since it's not defined in any C standard we should probably leave the work-around in for now.

Ideally, we'd purge "negative values = badness" behavior from the library and could then get rid of the types, but since ssize_t and hssize_t are used in the public API we're stuck with them for now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not do something similar to h[s]size_t, i.e., have a description for users and then an \internal elaboration?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because ssize_t is a POSIX type and people can google for its purpose. We don't need to Doxygen up wrappers that paper over platform inconsistencies.

#if H5_SIZEOF_SSIZE_T == 0
/* Undefine this size, we will re-define it in one of the sections below */
#undef H5_SIZEOF_SSIZE_T
Expand All @@ -235,137 +242,47 @@ typedef long long ssize_t;
#endif
#endif

/* int64_t type is used for creation order field for links. It may be
* defined in Posix.1g, otherwise it is defined here.
*/
Copy link
Member Author

@derobins derobins May 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Obsolete as we require C99 types now. Ditto uint64_t and uint32_t, below.

#if H5_SIZEOF_INT64_T >= 8
#elif H5_SIZEOF_INT >= 8
typedef int int64_t;
#undef H5_SIZEOF_INT64_T
#define H5_SIZEOF_INT64_T H5_SIZEOF_INT
#elif H5_SIZEOF_LONG >= 8
typedef long int64_t;
#undef H5_SIZEOF_INT64_T
#define H5_SIZEOF_INT64_T H5_SIZEOF_LONG
#elif H5_SIZEOF_LONG_LONG >= 8
typedef long long int64_t;
#undef H5_SIZEOF_INT64_T
#define H5_SIZEOF_INT64_T H5_SIZEOF_LONG_LONG
#else
#error "nothing appropriate for int64_t"
#endif

/* uint64_t type is used for fields for H5O_info_t. It may be
* defined in Posix.1g, otherwise it is defined here.
/**
* The size of file objects.
*
* \internal Defined as a (minimum) 64-bit integer type.
*/
#if H5_SIZEOF_UINT64_T >= 8
#ifndef UINT64_MAX
#define UINT64_MAX ((uint64_t)-1)
#endif
#elif H5_SIZEOF_INT >= 8
typedef unsigned uint64_t;
#define UINT64_MAX UINT_MAX
#undef H5_SIZEOF_UINT64_T
#define H5_SIZEOF_UINT64_T H5_SIZEOF_INT
#elif H5_SIZEOF_LONG >= 8
typedef unsigned long uint64_t;
#define UINT64_MAX ULONG_MAX
#undef H5_SIZEOF_UINT64_T
#define H5_SIZEOF_UINT64_T H5_SIZEOF_LONG
#elif H5_SIZEOF_LONG_LONG >= 8
typedef unsigned long long uint64_t;
#define UINT64_MAX ULLONG_MAX
#undef H5_SIZEOF_UINT64_T
#define H5_SIZEOF_UINT64_T H5_SIZEOF_LONG_LONG
#else
#error "nothing appropriate for uint64_t"
#endif

/*
* The sizes of file objects have their own types defined here, use a minimum
* 64-bit type.
*/
#if H5_SIZEOF_LONG_LONG >= 8
H5_GCC_DIAG_OFF("long-long")
typedef unsigned long long hsize_t;
typedef signed long long hssize_t;
H5_GCC_DIAG_ON("long-long")
#define PRIdHSIZE H5_PRINTF_LL_WIDTH "d"
#define PRIiHSIZE H5_PRINTF_LL_WIDTH "i"
#define PRIoHSIZE H5_PRINTF_LL_WIDTH "o"
#define PRIuHSIZE H5_PRINTF_LL_WIDTH "u"
#define PRIxHSIZE H5_PRINTF_LL_WIDTH "x"
#define PRIXHSIZE H5_PRINTF_LL_WIDTH "X"
#define H5_SIZEOF_HSIZE_T H5_SIZEOF_LONG_LONG
#define H5_SIZEOF_HSSIZE_T H5_SIZEOF_LONG_LONG
#define HSIZE_UNDEF ULLONG_MAX
#else
#error "nothing appropriate for hsize_t"
#endif
typedef uint64_t hsize_t;
/**
* The size of file objects. Used when negative values are needed to indicate errors.
*
* \internal Defined as a (minimum) 64-bit integer type. Use of hssize_t
* should be discouraged in new code.
*/
typedef int64_t hssize_t;
#define PRIdHSIZE PRId64
#define PRIiHSIZE PRIi64
#define PRIoHSIZE PRIo64
#define PRIuHSIZE PRIu64
#define PRIxHSIZE PRIx64
#define PRIXHSIZE PRIX64
#define H5_SIZEOF_HSIZE_T 8
#define H5_SIZEOF_HSSIZE_T 8
#define HSIZE_UNDEF UINT64_MAX
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we require C99 types and format specifiers now, we can more simply define h(s)size_t and haddr_t.


/*
* File addresses have their own types.
*/
#if H5_SIZEOF_INT >= 8
typedef unsigned haddr_t;
#define HADDR_UNDEF UINT_MAX
#define H5_SIZEOF_HADDR_T H5_SIZEOF_INT
#ifdef H5_HAVE_PARALLEL
#define HADDR_AS_MPI_TYPE MPI_UNSIGNED
#endif /* H5_HAVE_PARALLEL */
#define PRIdHADDR "d"
#define PRIoHADDR "o"
#define PRIuHADDR "u"
#define PRIxHADDR "x"
#define PRIXHADDR "X"
#elif H5_SIZEOF_LONG >= 8
typedef unsigned long haddr_t;
#define HADDR_UNDEF ULONG_MAX
#define H5_SIZEOF_HADDR_T H5_SIZEOF_LONG
#ifdef H5_HAVE_PARALLEL
#define HADDR_AS_MPI_TYPE MPI_UNSIGNED_LONG
#endif /* H5_HAVE_PARALLEL */
#define PRIdHADDR "ld"
#define PRIoHADDR "lo"
#define PRIuHADDR "lu"
#define PRIxHADDR "lx"
#define PRIXHADDR "lX"
#elif H5_SIZEOF_LONG_LONG >= 8
typedef unsigned long long haddr_t;
#define HADDR_UNDEF ULLONG_MAX
#define H5_SIZEOF_HADDR_T H5_SIZEOF_LONG_LONG
#ifdef H5_HAVE_PARALLEL
#define HADDR_AS_MPI_TYPE MPI_LONG_LONG_INT
#endif /* H5_HAVE_PARALLEL */
#define PRIdHADDR H5_PRINTF_LL_WIDTH "d"
#define PRIoHADDR H5_PRINTF_LL_WIDTH "o"
#define PRIuHADDR H5_PRINTF_LL_WIDTH "u"
#define PRIxHADDR H5_PRINTF_LL_WIDTH "x"
#define PRIXHADDR H5_PRINTF_LL_WIDTH "X"
#else
#error "nothing appropriate for haddr_t"
#endif
/**
* The address of an object in the file.
*
* \internal Defined as a (minimum) 64-bit unsigned integer type.
*/
typedef uint64_t haddr_t;
#define PRIdHADDR PRId64
#define PRIoHADDR PRIo64
#define PRIuHADDR PRIu64
#define PRIxHADDR PRIx64
#define PRIXHADDR PRIX64
#define H5_SIZEOF_HADDR_T 8
#define HADDR_UNDEF UINT64_MAX
#define H5_PRINTF_HADDR_FMT "%" PRIuHADDR
#define HADDR_MAX (HADDR_UNDEF - 1)

/* uint32_t type is used for creation order field for messages. It may be
* defined in Posix.1g, otherwise it is defined here.
*/
#if H5_SIZEOF_UINT32_T >= 4
#elif H5_SIZEOF_SHORT >= 4
typedef short uint32_t;
#undef H5_SIZEOF_UINT32_T
#define H5_SIZEOF_UINT32_T H5_SIZEOF_SHORT
#elif H5_SIZEOF_INT >= 4
typedef unsigned int uint32_t;
#undef H5_SIZEOF_UINT32_T
#define H5_SIZEOF_UINT32_T H5_SIZEOF_INT
#elif H5_SIZEOF_LONG >= 4
typedef unsigned long uint32_t;
#undef H5_SIZEOF_UINT32_T
#define H5_SIZEOF_UINT32_T H5_SIZEOF_LONG
#else
#error "nothing appropriate for uint32_t"
#ifdef H5_HAVE_PARALLEL
#define HADDR_AS_MPI_TYPE MPI_LONG_LONG_INT
#endif

//! <!-- [H5_iter_order_t_snip] -->
Expand Down