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

Fix arithmetics overflow warnings with VS2019 #1877

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

obones
Copy link
Contributor

@obones obones commented Nov 16, 2021

This fixes warnings of this kind, seen via #1866:

Warning C26451 Arithmetic overflow: Using operator '' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator '' to avoid overflow (io.2).

@@ -116,7 +116,7 @@ float magnitude_true_cs16(int16_t const *iq_buf, uint16_t *y_buf, uint32_t len)
for (i = 0; i < len; i++) {
int32_t x = iq_buf[2 * i];
int32_t y = iq_buf[2 * i + 1];
y_buf[i] = (int)sqrt(x * x + y * y) >> 1; // max 46341, scaled 23170, fs 16384
y_buf[i] = (int)sqrt((double)x * x + (double)y * y) >> 1; // max 46341, scaled 23170, fs 16384
Copy link
Owner

Choose a reason for hiding this comment

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

The code is fixed point by design.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, but sqrt takes a double which is why there is the warning.

Copy link
Owner

Choose a reason for hiding this comment

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

I think that sqrtf() should work and is slightly better type wise. If it is better accuracy wise I don't know.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I guess the point is that x and y are limited to [-128,127] because of iq_buf being bytes, but the compiler is not figuring it out? Is there in fact an overflow possibility, as determined by a human reviewing? Or is it a false positive warning. The position I have seen elsewhere, and tend to agree with, is that code should be fixed for valid warnings, and not modified much if any for invalid warnings, except that restructuring it slightly to be easier to reason about, withtout hurting the generated code is ok.

@@ -85,7 +85,7 @@ float magnitude_true_cu8(uint8_t const *iq_buf, uint16_t *y_buf, uint32_t len)
for (i = 0; i < len; i++) {
int16_t x = iq_buf[2 * i] - 128;
int16_t y = iq_buf[2 * i + 1] - 128;
y_buf[i] = (uint16_t)(sqrt(x * x + y * y) * 128.0); // max 181, scaled 23170, fs 16384
y_buf[i] = (uint16_t)(sqrt((double)x * x + (double)y * y) * 128.0); // max 181, scaled 23170, fs 16384
Copy link
Owner

Choose a reason for hiding this comment

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

This should be fixed point but I guess there is a reason for the 128.0.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I believe the reason is more about sqrt taking a double instead of a float

Copy link
Collaborator

Choose a reason for hiding this comment

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

This is just a test function, still turning int muls into double muls isn't great.

Copy link
Owner

Choose a reason for hiding this comment

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

And same here with sqrtf().

device.gap_limit = to_us * (hist_gaps.bins[1].max + 1); // Set limit above next lower gap
device.reset_limit = to_us * (hist_gaps.bins[hist_gaps.bins_count - 1].max + 1); // Set limit above biggest gap
device.gap_limit = to_us * (hist_gaps.bins[1].max + 1.0); // Set limit above next lower gap
device.reset_limit = to_us * (hist_gaps.bins[hist_gaps.bins_count - 1].max + 1.0); // Set limit above biggest gap
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not great, it was int addition before, now it's double addition.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, yes, the warning is about doing a 4 byte addition that then gets promoted to an 8 byte type for the multiplication, potentially leading to an overflow.
Using the floating point constant forces double computation which is not great, I agree. But how do I get rid of the warning then?

Copy link
Owner

Choose a reason for hiding this comment

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

This is non performance critical code. I'm fine with this change here but maybe it should be a cast? gap_limit is (float) while to_us is (double).

@obones
Copy link
Contributor Author

obones commented Jan 9, 2023

I have just rebased this branch on the latest master, please let me know if this is still of interest

@zuckschwerdt
Copy link
Collaborator

Yes, these clean-ups are of interest. I really need to find quiet time to contemplate the effects (e.g. changing some double calcs to float only).

@obones obones force-pushed the warnings_arithmetics_overflow branch from 16d39f2 to 1285116 Compare October 3, 2023 08:39
@@ -126,7 +126,7 @@ float magnitude_true_cs16(int16_t const *iq_buf, uint16_t *y_buf, uint32_t len)

// Fixed-point arithmetic on Q0.15
#define F_SCALE 15
#define S_CONST (1 << F_SCALE)
#define S_CONST ((int)(1 << F_SCALE))
Copy link
Collaborator

Choose a reason for hiding this comment

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

This surprises me. What type is 1<< F_SCALE without a cast. unsigned int?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants