-
Notifications
You must be signed in to change notification settings - Fork 215
Discussion: remove mp_set_long specialization #194
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
Conversation
|
Same for mp_get_long. But this is open for discussion. The compilers I am using optimize such things. And for more stupid compilers this will just result in one additional untaken branch. It is hardly worth the extra code. |
|
Well, I think the Travis build will show why this specialization was necessary ;-) |
|
Ok, I am curious. I didn't test it. Is there an overflow issue or something? |
|
Hint: the "<<" operator cannot shift more than the size of the data-type. |
|
Can it happen that DIGIT_SIZE > 8*sizeof(long)? Isn't shifting by the size of the datatype well defined? I think I just compiled the unspecialized version and my compiler did not warn. But maybe I used a different digit size. I will check. |
It can happen that sizeof(long)==4 and DIGIT_SIZE == 60. So, the answer is Yes, unfortunately. |
|
bn_mp_set_long.c: In function ‘mp_set_long’: |
|
@nijtmans Ok to merge then? With the shifting fix the generated code is equivalent to the specialized code. |
any reasonably intelligent compiler will optimize the loop away
nijtmans
left a comment
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'm OK with this change.
|
As far as I remember : we need to make everything explicit here at LTM, including operator precedence, which means parentheses around |
|
@sjaeckel ready to merge :) |
tommath_private.h
Outdated
| while (b != 0u) { \ | ||
| a->dp[x++] = ((mp_digit)b & MP_MASK); \ | ||
| b >>= DIGIT_BIT; \ | ||
| if (CHAR_BIT * sizeof (b) <= DIGIT_BIT) { break; } \ |
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 was just writing this comment while you pushed the change...
my question is if it is really CHAR_BIT as suggested by @czurnieden or if 8 is correct...
I think of platforms like some DSP's where CHAR_BIT is 16 or 32
I guess the 8 must stay, but I'm not 100% sure yet and I've to leave...
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, probably. Since sizeof always counts bytes??
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.
But we have sizeof*CHAR_BIT at other places too. Then we would have to remove all of those and replace with 8.
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.
According to stackoverflow, sizeof is always bytes. https://stackoverflow.com/questions/11868211/does-sizeof-return-the-number-of-bytes-or-the-number-of-octets-of-a-type-in-c
Therefore the usage of CHAR_BIT is wrong at many places in tommath. I can fix this in a separate PR if you wish.
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.
Ah and bytes are implementation defined. Hehe. This is shit.
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.
@sjaeckel Please merge as is and we resolve the CHAR_BIT question in a separate PR. If we want to resolve it...
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.
Ah and bytes are implementation defined. Hehe. This is shit.
Oh, yes! *deep sigh*
To quote the standard (ISO/IEC 9899:2011 (E). I'm still too stingy to get the new one)
3.6(emphasis mine)
1 byte
addressable unit of data storage large enough to hold any member of the basic character set of the execution environment
2 NOTE 1 It is possible to express the address of each individual byte of an object uniquely.
3 NOTE 2 A byte is composed of a contiguous sequence of bits, the number of which is implementation-defined. The least significant bit is called the low-order bit; the most significant bit is called the high-order bit.
But also
6.5.3.4 The sizeof and _Alignof operators
…
2 The sizeof operator yields the size (in bytes) of its operand, […]
4 When sizeof is applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1.
So you can get the size of a byte with all standard compliant compilers where it is in CHAR_BIT. But what is with all of the non-standard compliant compilers? They are not supported, you said? Well, we really need a list of supported ones somewhere in a place where we can point at it if somebody wants to blame us for the problems one of the many crappy c-compilers out there gave them.
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 at least CHAR_BIT=BYTES_BIT. Then it is correct as it is now :)
(size_t)XXX". The (size_t) cast doesn't add anything here.
|
Well, I see the construct "sizeof(yyy) * (size_t) CHAR_BIT" in a lot of places. To me the (size_t) cast doesn't add anything here: since sizeof() already returns a size_t, what's wrong with multiplying that to an "int", giving a size_t result? As I read the C-spec, usages of CHAR_BIT is correct here. It could be 8, 16 or whatever. |
|
@nijtmans While I don't have anything against you or other collaborators editing my PRs, I would prefer if you keep create a separate PR for the separate issue you observed. Nevertheless, I also didn't like these unnecessary size_t casts and would like to see them gone 👍 |
|
So, it looks like we are in full agreement here! ;-) |
|
Since this PR already has 5 commits, I think @sjaeckel will want us to do this commit again anyway, to keep a clean history in GIT. Well, then we can split it, now we know how it should look like. But if @sjaeckel accepts it as-is that would be easier for us. For me 5 commits like this is acceptable. |
Still not activated by default since demo.c has many issues. Furthermore there are issues in the system headers due to Wsystem-headers.
|
@nijtmans I suggest to split this into two cleaned-up PRs. One for the mp_set_long specialization and the second one fixing the casts etc. Do you agree? |
|
I agree with splitting this into 2 PR's. Thanks for the -Wconversion and -Wsign-conversion fixes. It looks like I was too rigid in the (size_t) removals ;-) |
|
Shall I do the split? |
|
Yes, go ahead! I'll put my approval there! |
any reasonably intelligent compiler will optimize the loop away
ping @nijtmans @sjaeckel