-
Notifications
You must be signed in to change notification settings - Fork 168
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
64bit expressions used in #[el]if statements #1389
Comments
It happens on Win32/Win64 hosted compilers (I tested both). Linux hosted is said to be okay. This was done by Przemyslaw to workaround truncations in these macros: |
The issue is caused by C standard. |
I suppose "LONGLONG" ints shouldn't be enabled in compiler too if preprocessor in this mode is strictly limited? Why enable 64-bit ints for compiler in C89 mode? |
It is for backward compatibility with previous OW and Watcom versions and compatibility with C standard. |
Now i'm just curious what was different in a ~2020 OW, which didn't manifest anything like that... |
Do you want to say that in current version is bug? |
New preprocessor was introduced by following commit Commit 546c585 |
|
It is irrelevant what was doing older version, only C standard is relevant. |
Hmm, don't need to explain that , we're quite used to what's possible under ANSI C. Anyway OpenWatcom also set up kind of it's own standard after all these years ;-) |
Older didn't truncate PP in this scenario either. We looked as far as #include "limits.h"
#include "stdint.h"
#include "stdio.h"
/* extracted from hbdefs.h */
#if ! defined( LONGLONG_MAX )
#if defined( _I64_MAX )
#define LONGLONG_MAX _I64_MAX
#elif defined( LLONG_MAX )
#define LONGLONG_MAX LLONG_MAX
#elif defined( LONG_LONG_MAX )
#define LONGLONG_MAX LONG_LONG_MAX
#else
#define LONGLONG_MAX 9223372036854775807LL
#endif
#endif
void main()
{
#if LONGLONG_MAX < LONG_MAX
#error "BUG"
#endif
printf("LONG_MAX %d\n", LONG_MAX );
printf("LONGLONG_MAX %I64d\n", LONGLONG_MAX );
} (redacted, preprocessor case only) |
Sorry, but C++ compiler work with different standard C++98 I don't know how much it is different from C89 or C99. Maybe it looks like old version worked correctly in some situation but how can have precision if all internal variables were 32-bit. It is not about macro value. |
Case just shows what we know about it, thanks for looking at it. Lastly, I can confirm that cross building from Linux results are the same as Win32/Win64 - there is no difference between host platforms, so the "Win32 version" may be discarded from title of this issue. |
Older preprocessor overflowed on ops (as one could expect), but somehow processed comparisons of constants in macros. #if LONG_MAX + 1 < LONG_MAX
#error "BUG arithmetic"
#endif is different to (in pre December 2020) #if 2147483648 < 2147483647
#error "BUG comparison"
#endif If compiler exposes 64-bit datatypes in C89 mode, then preprocessor I think should at least emit truncation warnings, as it may result in very unsafe code silently, if someone trusted OpenWatcom's preprocessor. Also there is this what fails now: #if 2147483648I64 < 2147483647I64
#error "BUG comparison I64"
#endif |
Thanks for you investigation. But I think old behaviour mask the fact that all processing of expressions is 32-bit because comparison of simple constant items doesn't go to the expression evaluation and was processed differently. Question is what is correct? anyway you look on this from 64-bit point of view, but earlier it was 32-bit world and nobody has this problem that signal something as overflow was non-sense and is not required by standard. Take into account that
and
can be a problem in old version. |
Such warning, if you implement it, would be not for C standards of course (if having the cleanest C89 compiler is your goal). That would be for OpenWatcom users that implemented some 64-bit code over the years and will upgrade to current. They could have not use -za99 just like us, because 64-bit int was available anyway. |
I looked at it from all sides and came up with the following less incorrect solution. I will modify OW 2.0 to use only 64-bit processing in the pre-processor for both standards (C89 and C99). Here are some facts from history and reasons for my decision.
I assume that no one will have a problem with that, the pre-processor will work correctly even if it is not 100% backward compatible. |
Now preprocessor of C compiler is fixed that use 64-bit precision for constant expression evaluation in both modes C89 and C99. By example by C standard folowing text is simple preprocessor number token 0XZB54. You can try it with other compilers but using of 2147483648I64 in preprocessor #if condition is invalid. Probably some diagnostics message should be add into preprocessor expression evaluator if incorrect number is passed to preprocessor, because it can be typical mistake. most of programmers don't know how preprocesor tokenize input stream and what preprocessor number is and think that preprocessor process C numbers but it is not true. |
C compiler preprocesor number doesn't have any type and by example don't know octal or hexadecimal number format only integer numbers in decadic representation therefore you can not use most of C macros in preprocessor #if statement because results can be really surprising. |
Anyway I will check if reprocessing tokens in constant expression in preprocessor is correct with regards to C99 standard. |
Please recheck with fixed precision of constant expression evaluation. #if 2147483648I64 < 2147483647I64 works for me in both modes. |
correct preprocessor in C89 mode to use 64-bit precision for expression evaluation Now same behavior in C89 and C99 mode correct now wrong tests for preprocessor after fixing precision
Thank you for progressing with these. Yes, the idea of this2147483647I64, etc. was extracted by me from OW limits.h, so it was checked rather out of curiosity what if I'm using them indirectly. |
I was not sure how it is going exactly it is long time than I touch pre-processing I remember that it is really a little strange. I hope that it will works, because there should not be change, change is only in expression evaluation on last tokenization that it should process C tokens. It means that 2147483647I64 should be processed without problems because it is valid C tokens 2147483647 + I + 64 and it is processed as constant number. |
Please recheck and confirm if OK or you have still some issues. |
I've downloaded Last-CI-build and redone the tests, so far it looks good to me. Thanks Jiří! |
Thanks for confirmation. |
Hi,
@jmalak can you look at the original message 64bit expressions used in #[el]if statements about subj?
Thanks
The text was updated successfully, but these errors were encountered: