-
Notifications
You must be signed in to change notification settings - Fork 30
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
Fix warnings on 32-bit platforms #159
Conversation
Signed-off-by: voidbert <[email protected]>
@@ -299,7 +299,8 @@ bool config_to_color(const char* text, argb_t* color) | |||
++text; | |||
} | |||
|
|||
if (!str_to_num(text, 0, &num, 16) || num < 0 || num > 0xffffffff) { | |||
if (!str_to_num(text, 0, &num, 16) || num < 0 || | |||
(uint64_t)num > (uint64_t)0xffffffff) { |
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.
Do we really need these type casts?
0xffffffff
fits uint32_t. Also color is always 32 bits.
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.
On 32-bit systems, 0xffffffff
will be considered a 4-byte unsigned int
by compilers, as it can't fit in an int
without overflowing. Also, ssize_t num
will be a 4-byte int
(not guaranteed by the C spec, but what compilers usually do). The compiler will emit a warning because these two different types are being compared, and the compiler doesn't know whether it should generate a signed or unsigned comparison. The cast to uint64_t
assures that these two values can be safely compared on both 32-bit and 64-bit systems. On 64-bit systems, because this code checks for the validity of a color, num
can be greater than 32-bits (it's inputted by the user in the configuration file). A cast of num
to uint32_t
wouldn't suffice, as values higher than 0xffffffff
would be accepted as valid colors, as they'd be truncated before the comparison.
@@ -157,8 +157,8 @@ static struct wl_buffer* create_buffer(void) | |||
|
|||
// generate unique file name | |||
clock_gettime(CLOCK_MONOTONIC, &ts); | |||
snprintf(path, sizeof(path), "/" APP_NAME "_%lx", | |||
(ts.tv_sec << 32) | ts.tv_nsec); | |||
snprintf(path, sizeof(path), "/" APP_NAME "_%" PRIx64, |
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.
It would be better to use one style for printf.
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.
Sorry, but I don't know what you mean by this. PRIx64
is the best way to print an uint64_t
independently of the size unsigned long ("%lx")
or unsigned long long ("%llx")
might have. Another option would be casting the value in the arguments to an unsigned long long
, and %llx
can be used instead of PRIx64
. I can patch that in if you wish.
@@ -15,7 +17,7 @@ | |||
// Special ids for windows size and position | |||
#define SIZE_FROM_IMAGE 0 | |||
#define SIZE_FROM_PARENT 1 | |||
#define POS_FROM_PARENT 0xffffffff | |||
#define POS_FROM_PARENT SSIZE_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.
I don't see a reason to change this. What the purpose?
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.
0xffffffff
may be too large for an ssize_t
, and some functions (ui_get_x
and ui_get_y
) return this value as an ssize_t
. I see that POS_FROM_PARENT
is a special return value: normal positions can be returned, so can this very large value, which has a special meaning. This way, SSIZE_MAX
is for sure the greatest value that can fit in an ssize_t
.
I hereby attach the warnings that resulted from compiling warnings.txt
|
Sounds reasonable, thank you! |
Fixed code that assumed the size of some integer types to be a fixed number of bytes, when it can very between platforms. The warnings fixed were:
printf
formats forsize_t
. Now, the platform-independent%zu
(C99 required);time_t
may be less than 64 bits, requiring a cast to a bigger size if a left shift by 32 bits is used.POS_FROM_PARENT
may assume a value too large forssize_t
.I didn't test if these warnings caused any runtime errors, but they can do so, so it's better to have them fixed.