-
-
Notifications
You must be signed in to change notification settings - Fork 6.6k
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
warnless: simplify type size handling by using sizeof(T) #7181
Conversation
9ff7963
to
a6f7fb5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I appreciate how this makes things simpler!
lib/warnless.c
Outdated
#endif | ||
|
||
if(sizeof(int) < sizeof(size_t)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be made into a preprocessor directive;
#if UINT_MAX < SIZE_T_MAX
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be made into a preprocessor directive;
#if UINT_MAX < SIZE_T_MAX
The reason why I decided using if(sizeof(int) < sizeof(size_t))
instead of preprocessor defines is to have maximum portability (any complier has sizeof
, negate and shift operators), if this or that define is missing, like for example SIZE_T_MAX
which may be missing in some older MSVC versions, if I am not mistaken, then proposed simplification will run into additional checks for defines existence.
if(sizeof(int) < sizeof(size_t))
is removed by the compiler with any optimization level and therefore has no effect on performance while being effective check in the same time against types inconsistency.
I can of course replace to compile time preprocessor directives but anxious about portability. What do you think about my reasoning?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thing is, we use those defines in existing curl source code so we already need to have them available, using them in this file is thus not any added portability issue. I realize a compiler can remove the fixed value condition, but I'm concerned about warnings and that the assert is also a null-operation in non-debug builds so it makes a fixed condition to a blank expression.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I see. I will adjust these checks to the preprocessor directives as proposed then.
lib/warnless.c
Outdated
#if (SIZEOF_INT < SIZEOF_LONG) | ||
DEBUGASSERT((unsigned long) slnum <= (unsigned long) CURL_MASK_SINT); | ||
#endif | ||
if(sizeof(int) < sizeof(long)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be made into a preprocessor directive:
#if INT_MAX < LONG_MAX
lib/warnless.c
Outdated
#if (SIZEOF_INT < SIZEOF_SIZE_T) | ||
DEBUGASSERT((size_t) sznum <= (size_t) CURL_MASK_SINT); | ||
#endif | ||
if(sizeof(int) < sizeof(size_t)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#if UINT_MAX < SIZE_T_MAX
lib/warnless.c
Outdated
DEBUGASSERT(uznum <= (size_t) CURL_MASK_ULONG); | ||
#ifdef _MSC_VER | ||
# pragma warning(push) | ||
# pragma warning(disable:4127) /* conditional expression is constant */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you convert to preprocessor conditions, maybe this pragma can be removed?
a6f7fb5
to
6a6de19
Compare
@bagder I made changes but had to introduce a missing |
…piler to define the required signed/unsigned mask
6a6de19
to
5bfd59c
Compare
Thanks! |
Simplify type size handling by using sizeof(T) and rely on the compiler to define the required signed/unsigned masks.
The idea is to get rid of SIZEOF_XXX defines, which are not needed for this implementation, and a manually created masks which can be generated by the compiler at compile time. In this case type masks are created by the compiler and can never be erroneous for any type.
Such run-time checks
if (sizeof(TYPE1) < sizeof(TYPE2))
are removed by the compiler during the optimization stage because the condition is constant, so there is no overhead. MSVC throws warning regarding the constant condition used but it is suppressed by the implementation.I am using this implementation for many years already without any issue (Linux, Android, Apple iOS, Windows Win32, Windows UWP).