You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I don't actually think there is a bug, but I'm looking for clarification. The issue is with the implementation for platforms where __uint128_t is not available (but I presume that it would be the same for the alternative implementation):
The -s triggers C4146, which is a level 2 diagnostic, but is elevated to an error if the /sdl compile directive is active. The issue came up when I've tried to build sqlsrv and pdo_sqlsrv, and I found microsoft/msphpsql#1496, where it has been suggested to deactivate /sdl (which, in my opinion, should be done for production builds anyway).
Now, if I'm not mistaken, applying unary minus to an unsigned operand is well-defined behavior (at least in C99), so either I'm mistaken, C++ behaves differently, or the warning is bogus.
But I would be somewhat unhappy to diverge from the reference implementation just to satisfy a compiler warning about perfectly legal code.
Now, if I'm not mistaken, applying unary minus to an unsigned operand is well-defined behavior (at least in C99), so either I'm mistaken, C++ behaves differently, or the warning is bogus.
My understanding is that the warning is a warning about possibly unexpected behavior for less-experienced C developers, just like clang’s -Wstring-plus-int:
#include<stdio.h>
int
main(void) {
printf("%s\n", "foo" + 1);
}
$ clang test.c
test.c:5:23: warning: adding 'int' to a string does not append to the string [-Wstring-plus-int]
printf("%s\n", "foo" + 1);
~~~~~~^~~
test.c:5:23: note: use array indexing to silence this warning
printf("%s\n", "foo" + 1);
^
& [ ]
1 warning generated.
The following (untested) patch might leave the code in a cleaner state than before, though, because php_random_pcgoneseq128xslrr64_rotr64 is not technically specific to u128 anyways:
But I would be somewhat unhappy to diverge from the reference implementation just to satisfy a compiler warning about perfectly legal code.
That is my point: if the warning is indeed bogus, we can just ignore it (or could disable it for that particular code fragment, if someone wants us to). And I'm still quite confident that the code is perfectly valid for C99; I'm still not sure about C++, though.
If you want me to check that patch, I'll gladly do it, but I'm not opposed to leave the code as is, particularly if it matches the reference implementation.
I am rather in favor of changing the reference implementation to suppress warnings. I don't think there is much benefit to be gained by following the reference implementation.
However, my C / C++ (especially C++) skills are not high and I would respect the views of the experts either way.
Hmm, I did a minimal PHP build with /w14146 (i.e. treat C4146 as level 1 warning), and got warnings raised all over the place. Fixing this in only public headers doesn't make sense to me (besides diverging from the reference implementation can make future updates harder).
Of course, we could generally suppress the warning, or for every single line (#pragma warning(suppress: 4146)), but neither solution appears sensible to me (at least when applying unary minus to literals, the warning makes sense, basically the same issue as https://3v4l.org/NsksW, and having #pragmas all over the place, probably guarded by #ifdef _MSC is ugly).
So either we replace all -u with (~u + 1), or we just ignore the issue, unless somebody complains. The former would be a small step to cleaner builds with MSVC (currently, we are only free of W1 warnings on x64), but might not as optimized by compilers.
Well, blindly replacing all -u with (~u + 1) doesn't look like a good idea, due to several macro definitions would be affected, and if these macros are applied to signed values, that might be bad.
So I ran a build with /sdl /wd4146 (i.e. disable C4146, but check for all other SDL related issues), and got a lot of C4703, e.g. for previous_filename in
That code looks perfectly fine, since the use is guarded by scope (which does not appear to change). I don't think it makes sense to try to fix all these probably bogus warnings.
Activity
TimWolla commentedon Jul 25, 2024
The reference implementation is here:
https://github.com/imneme/pcg-c/blob/83252d9c23df9c82ecb42210afed61a7b42402d7/include/pcg_variants.h#L96-L106
https://github.com/imneme/pcg-c/blob/83252d9c23df9c82ecb42210afed61a7b42402d7/include/pcg_variants.h#L243-L247
The code as implemented in PHP matches the signedness of the reference implementation.
TimWolla commentedon Jul 25, 2024
This could just be rewritten to
But I would be somewhat unhappy to diverge from the reference implementation just to satisfy a compiler warning about perfectly legal code.
My understanding is that the warning is a warning about possibly unexpected behavior for less-experienced C developers, just like clang’s
-Wstring-plus-int:TimWolla commentedon Jul 25, 2024
The following (untested) patch might leave the code in a cleaner state than before, though, because
php_random_pcgoneseq128xslrr64_rotr64is not technically specific to u128 anyways:cmb69 commentedon Jul 25, 2024
That is my point: if the warning is indeed bogus, we can just ignore it (or could disable it for that particular code fragment, if someone wants us to). And I'm still quite confident that the code is perfectly valid for C99; I'm still not sure about C++, though.
If you want me to check that patch, I'll gladly do it, but I'm not opposed to leave the code as is, particularly if it matches the reference implementation.
zeriyoshi commentedon Jul 26, 2024
I am rather in favor of changing the reference implementation to suppress warnings. I don't think there is much benefit to be gained by following the reference implementation.
However, my C / C++ (especially C++) skills are not high and I would respect the views of the experts either way.
cmb69 commentedon Jul 31, 2024
Hmm, I did a minimal PHP build with
/w14146(i.e. treat C4146 as level 1 warning), and got warnings raised all over the place. Fixing this in only public headers doesn't make sense to me (besides diverging from the reference implementation can make future updates harder).Of course, we could generally suppress the warning, or for every single line (
#pragma warning(suppress: 4146)), but neither solution appears sensible to me (at least when applying unary minus to literals, the warning makes sense, basically the same issue as https://3v4l.org/NsksW, and having#pragmas all over the place, probably guarded by#ifdef _MSCis ugly).So either we replace all
-uwith(~u + 1), or we just ignore the issue, unless somebody complains. The former would be a small step to cleaner builds with MSVC (currently, we are only free of W1 warnings on x64), but might not as optimized by compilers.cmb69 commentedon Jul 31, 2024
Well, blindly replacing all
-uwith(~u + 1)doesn't look like a good idea, due to several macro definitions would be affected, and if these macros are applied to signed values, that might be bad.So I ran a build with
/sdl /wd4146(i.e. disable C4146, but check for all other SDL related issues), and got a lot of C4703, e.g. forprevious_filenameinphp-src/Zend/zend_ast.c
Lines 551 to 565 in a578c27
That code looks perfectly fine, since the use is guarded by
scope(which does not appear to change). I don't think it makes sense to try to fix all these probably bogus warnings.TimWolla commentedon Jul 31, 2024
So, should we close this as Wont Fix then?
cmb69 commentedon Jul 31, 2024
Yes.