Date: Fri, 18 Jul 2025 15:56:59 +0100
On Friday, July 18, 2025, David Brown wrote:
> Finally, I suggest you stop writing nonsense in your code. A TCP/IP port
> is a number between 1 and 65535 (UDP allows port 0 in some circumstances to
> mean "no port"). If you have a number and you want to check its validity
> as a port number, check it against these two values - 1 and 65535 (or
> 0xffff if you prefer hex, or define an identifier for it if you think it
> makes the code clearer). Using "-1" as a maximum value for an unsigned
> type is nonsense.
I have a trick I do with unsigned numbers in multi-threaded programs.
I define the variable, maybe something like:
std::atomic< std::size_t > n{0u};
0 is an invalid number.
The first threads starts the second thread. The second thread assigns to
'n'. If the second thread fails, 'n' remains as zero... but that's a
problem if the first thread does this:
n.wait(0u);
Therefore in the second thread, I set 'n' to its max value upon failure so
that the first thread will unblock.
So when I'm dealing with an unsigned integer variable shared between
multiple threads, I blacklist 0 and its max value as invalid, like this:
if ( 0u==n || -1==n ) . . .
But from now on I'll write:
if ( 0u==n || _Max==n ) . . .
Of course I could instead use a second variable, maybe a semaphore or a
condition variable or an atomic boolean, but I like my strategy, which can
be summed up as: "If all the bits are the same, it's invalid".
I've already committed the new header file '_Max.hpp' to my project and
eradicated uses of -1 for unsigned types:
#ifndef HEADER_INCLUSION_GUARD_fbde6307_28ac_4082_904d_2984d8802179
#define HEADER_INCLUSION_GUARD_fbde6307_28ac_4082_904d_2984d8802179
#include <limits> // numeric_limits<T>::max()
#include <type_traits> // is_integral, is_unsigned
struct _Max_t {
template<typename T> requires std::is_integral_v<T> &&
std::is_unsigned_v<T>
constexpr operator T(void) const
{
// Some compilers define 'max' as a preprocessor macro
// function, so we use a function pointer here.
constexpr auto FuncPtr = &std::numeric_limits<T>::max;
return FuncPtr();
}
template<typename T> requires std::is_integral_v<T> &&
std::is_unsigned_v<T>
constexpr bool operator==(T const n) const
{
// Some compilers define 'max' as a preprocessor macro
// function, so we use a function pointer here.
constexpr auto FuncPtr = &std::numeric_limits<T>::max;
return n == FuncPtr();
}
};
constexpr _Max_t _Max{};
#endif
> Finally, I suggest you stop writing nonsense in your code. A TCP/IP port
> is a number between 1 and 65535 (UDP allows port 0 in some circumstances to
> mean "no port"). If you have a number and you want to check its validity
> as a port number, check it against these two values - 1 and 65535 (or
> 0xffff if you prefer hex, or define an identifier for it if you think it
> makes the code clearer). Using "-1" as a maximum value for an unsigned
> type is nonsense.
I have a trick I do with unsigned numbers in multi-threaded programs.
I define the variable, maybe something like:
std::atomic< std::size_t > n{0u};
0 is an invalid number.
The first threads starts the second thread. The second thread assigns to
'n'. If the second thread fails, 'n' remains as zero... but that's a
problem if the first thread does this:
n.wait(0u);
Therefore in the second thread, I set 'n' to its max value upon failure so
that the first thread will unblock.
So when I'm dealing with an unsigned integer variable shared between
multiple threads, I blacklist 0 and its max value as invalid, like this:
if ( 0u==n || -1==n ) . . .
But from now on I'll write:
if ( 0u==n || _Max==n ) . . .
Of course I could instead use a second variable, maybe a semaphore or a
condition variable or an atomic boolean, but I like my strategy, which can
be summed up as: "If all the bits are the same, it's invalid".
I've already committed the new header file '_Max.hpp' to my project and
eradicated uses of -1 for unsigned types:
#ifndef HEADER_INCLUSION_GUARD_fbde6307_28ac_4082_904d_2984d8802179
#define HEADER_INCLUSION_GUARD_fbde6307_28ac_4082_904d_2984d8802179
#include <limits> // numeric_limits<T>::max()
#include <type_traits> // is_integral, is_unsigned
struct _Max_t {
template<typename T> requires std::is_integral_v<T> &&
std::is_unsigned_v<T>
constexpr operator T(void) const
{
// Some compilers define 'max' as a preprocessor macro
// function, so we use a function pointer here.
constexpr auto FuncPtr = &std::numeric_limits<T>::max;
return FuncPtr();
}
template<typename T> requires std::is_integral_v<T> &&
std::is_unsigned_v<T>
constexpr bool operator==(T const n) const
{
// Some compilers define 'max' as a preprocessor macro
// function, so we use a function pointer here.
constexpr auto FuncPtr = &std::numeric_limits<T>::max;
return n == FuncPtr();
}
};
constexpr _Max_t _Max{};
#endif
Received on 2025-07-18 14:57:02