Closed hckr closed 7 years ago
Thank you for your PR. I am pretty sure your commit does not break anything and can't see any reason to reject it if it works for you but I don't understand how removing a warning would fix anything. Could you be more specific about issues you meet? On what architecture (32bit/64bit) do you work? There may be a real issue to work on for a real patch and it would be sad not to take this opportunity to address it properly.
I use gcc 6.3.1 on 64-bit. In this version warning -Wnarrowing
seems to be treated as error and causes compilation to fail.
As I took a closer look it seems there might be a real issue which is just being hidden by proposed suppresion.
short
(which is a shortcut for signed short int
) has the size of 16 bits minimum (max. value being 32768
) but in the code much larger values are used (40712, 39054, ...):
static const short asincof_r0[] = { 0x9f08, 0x988e, 0x4fc3, 0x3f68 };
But on the other hand those values are in hex, so they might have been hand-picked and are later are e. g. treated as unsigned (in which case desclarations should be changed to unsigned
) or something else. I don't know, but author should know his intensions. :)
It was surprised that library code doesn't compile and assumed that code works correctly and compiler just started to be more picky in this area.
Thank you for digging in that far. The coefficients you are referring to come from here: https://github.com/jeremybarnes/cephes/blob/master/cmath/asin.c#L222
Could you maybe try with your compiler and see if you get any warnings there?
I see a #if MIEEE
(it seems to basically mean big endian) there, maybe I am assuming too much...
I digged a bit in the code and found out those values are treated as something else – doubles (sse2_math.h#L175):
static const __m128d _mm_cst_pd_asincof_r0 = _mm_set1_pd(*(double*) asincof_r0);
static const __m128d _mm_cst_pd_asincof_r1 = _mm_set1_pd(*(double*) asincof_r1);
static const __m128d _mm_cst_pd_asincof_r2 = _mm_set1_pd(*(double*) asincof_r2);
static const __m128d _mm_cst_pd_asincof_r3 = _mm_set1_pd(*(double*) asincof_r3);
static const __m128d _mm_cst_pd_asincof_r4 = _mm_set1_pd(*(double*) asincof_r4);
It looks like some high level magic which I don't understand (why wouldn't someone just define it as simple double literals?, why array of short
s wasn't defined as array of unsigned shorts
?), but narrowing isn't an issue, because those arrays are interpreted as doubles anyway.
I think that changing library code isn't the wisest thing to do and personally solved the issue with a warning/error suppression.
It is just a way to represent a specific double precision float by its binary representation. But as you can see, I did not invent those numbers, just copy pasted them from a different code.
The thing here is just that I try to take advantage of SSE2 registers (if available ; still have to do AVX) to make the code faster. SSE2 instruction do not provide trigonometric functions so I had to code this again... But this part can also be commented out if results seem incorrect after your warning is raised.
For now, I will just merge the PR (your line doesn't hurt!), but I am still curious about the error raised. I don't want to take it the easy way and blame it on the compiler, but still, there must be some better way to secure that part...
Had an error with installation on Linux (see below), my addition of
-Wno-narrowing
compilation flag fixes it.