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

core/macros: fix SIGNOF() macro when applied to size_t #18849

Merged
merged 2 commits into from
Nov 9, 2022

Conversation

benpicco
Copy link
Contributor

@benpicco benpicco commented Nov 4, 2022

Contribution description

This is a strange one, for some reason when doing

size_t foo = 23;
return SIGNOF(foo);

none of the _Generics would match and we get

core/include/macros/math.h:34:62: error: comparison is always false due to limited range of data type [-Werror=type-limits]
   34 |                               default: (long long)(a) < 0 ? -1 : 1)
      |                                                       ^

Testing procedure

The updated unit test should compile.

Issues/PRs references

@github-actions github-actions bot added Area: core Area: RIOT kernel. Handle PRs marked with this with care! Area: tests Area: tests and testing framework labels Nov 4, 2022
@benpicco benpicco requested review from kfessel and maribu November 4, 2022 21:56
@benpicco benpicco added Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors) Impact: minor The PR is small in size and might only require a quick look of a knowledgeable reviewer labels Nov 4, 2022
@@ -31,7 +31,7 @@ extern "C" {
unsigned int: 1, \
unsigned long: 1, \
unsigned long long: 1, \
default: (long long)(a) < 0 ? -1 : 1)
default: (signed long)(a) < 0 ? -1 : 1)
Copy link
Contributor

Choose a reason for hiding this comment

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

shouldn't this be "signed long long" ?

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 thought so too, but when I would do that I'd still get the error.

Copy link
Member

Choose a reason for hiding this comment

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

Could you handle long long as special case to avoid loosing precision on the default? Otherwise we may end up with false results for 64 bit numbers.

Copy link
Contributor

@kfessel kfessel Nov 4, 2022

Choose a reason for hiding this comment

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

                              default: (0LL < ((long long) a)) ? (-1) : (1) )

worked for me no it did not

i checked and found long long to be longer than unsigned long (4 vs 8 bytes)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

hm this will make zero negative signed, but I hope that won't cause any issues…

Copy link
Contributor

Choose a reason for hiding this comment

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

no it is wrong i missed turning the < around

Copy link
Contributor Author

@benpicco benpicco Nov 4, 2022

Choose a reason for hiding this comment

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

Yea I figured. Still a > 0 will be false and return -1 for a == 0.

But I supposed we could say the sign of 0 is undefined…

Copy link
Contributor

Choose a reason for hiding this comment

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

the compiler also fails for uint32_t

Copy link
Contributor

Choose a reason for hiding this comment

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

doesn't the _generics system know about typedefs?

@kfessel
Copy link
Contributor

kfessel commented Nov 4, 2022

would

static int _signof(long long a){ return (0LL ) <= ( a ) ? (1) : (-1) ;}
#define SIGNOF(a) _Generic(a, unsigned char: 1,          \
                              unsigned short: 1,         \
                              unsigned int: 1,           \
                              unsigned long: 1,          \
                              unsigned long long: 1,     \
                              default: _signof(a) )

work for the usecases?

@kfessel
Copy link
Contributor

kfessel commented Nov 4, 2022

but the cast might also lead to wrong result if a is > uint64_max / 2

@benpicco
Copy link
Contributor Author

benpicco commented Nov 5, 2022

No, then it's not longer compile time const in so much that it can be used to statically initialize the size of an array.

@kfessel
Copy link
Contributor

kfessel commented Nov 5, 2022

something seems to be realy wrong it does not fail for uint64_t (but the cast may not be valid in that case ( values > uint64_max / 2 will be considered negative))

but if fails for uint32_t, uint16_t

@kfessel
Copy link
Contributor

kfessel commented Nov 5, 2022

may be the warning should just be disabled

or document that it only work up to long

@benpicco benpicco added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Nov 5, 2022
@riot-ci
Copy link

riot-ci commented Nov 5, 2022

Murdock results

✔️ PASSED

8f8bb6c tests/unittests: core: add test for SIGNOF(size_t)

Success Failures Total Runtime
1998 0 2000 06m:25s

Artifacts

This only reflects a subset of all builds from https://ci-prod.riot-os.org. Please refer to https://ci.riot-os.org for a complete build for now.

Copy link
Member

@maribu maribu left a comment

Choose a reason for hiding this comment

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

ACK, but please address and inline comment and squash before merging

core/include/macros/math.h Outdated Show resolved Hide resolved
@kfessel
Copy link
Contributor

kfessel commented Nov 7, 2022

@benpicco DIV_ROUND without signum

#define DIV_ROUND(a, b) ((a / b  + ((a % b >= (b) / 2) ? 1:0)))

core/include/macros/math.h Outdated Show resolved Hide resolved
@maribu maribu merged commit e402e3f into RIOT-OS:master Nov 9, 2022
@benpicco benpicco deleted the core-SIGNOF branch November 9, 2022 17:26
@kaspar030 kaspar030 added this to the Release 2023.01 milestone Jan 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: core Area: RIOT kernel. Handle PRs marked with this with care! Area: tests Area: tests and testing framework CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Impact: minor The PR is small in size and might only require a quick look of a knowledgeable reviewer Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants