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

64bit expressions used in #[el]if statements #1389

Open
omm opened this issue Jan 30, 2025 · 13 comments
Open

64bit expressions used in #[el]if statements #1389

omm opened this issue Jan 30, 2025 · 13 comments

Comments

@omm
Copy link

omm commented Jan 30, 2025

Hi,

@jmalak can you look at the original message 64bit expressions used in #[el]if statements about subj?

Thanks

@alcz
Copy link

alcz commented Jan 30, 2025

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:
harbour/core@e66aab7
harbour/core@6c8c5cd

@jmalak
Copy link
Member

jmalak commented Jan 30, 2025

The issue is caused by C standard.
C89 (default for OW) use 32-bit expression in pre-processor.
C99 define intmax_t/uintmax_t expression size in pre-processor, you need to use -za99 C compiler option to this behaviour.
I don't believe that on Linux it is different, it has nothing to do with host platform.

@alcz
Copy link

alcz commented Jan 30, 2025

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?

@jmalak
Copy link
Member

jmalak commented Jan 30, 2025

It is for backward compatibility with previous OW and Watcom versions and compatibility with C standard.
Any C89/C90 compliant compiler will have same problem.
Anyway such code uses undefined behaviour for C89/90 standard.

@alcz
Copy link

alcz commented Jan 30, 2025

Now i'm just curious what was different in a ~2020 OW, which didn't manifest anything like that...

@jmalak
Copy link
Member

jmalak commented Jan 30, 2025

Do you want to say that in current version is bug?
If yes, then specify which one and we can fix it.
But if in older version something worked in undefined behaviour then it doesn't means now it is wrong if doesn't.

@jmalak
Copy link
Member

jmalak commented Jan 30, 2025

New preprocessor was introduced by following commit

Commit 546c585
jmalak
committed
on Dec 6, 2020
implement new preprocessor constant expression processing with support for C99 standard (modified copy of ppexpn.c from C++ compiler)
in C89/90 mode constant expression is evaluated with 32-bit precision
in C99 mode constant expression is evaluated with 64-bit precision (OW intmax_t type)
master
·
Last-CI-build
2021-01-01-Build

@alcz
Copy link

alcz commented Jan 30, 2025

Version 2.0 beta Feb 5 2020 06:09:49 (32-bit)
is something I incidentally have on disk here. If you're interested, we can probably make a self contained example in a spare time. As far as undefined behaviours go. I can recheck current Linux host for these truncations too, if it's true that is different. I didn't test that myself.

@jmalak
Copy link
Member

jmalak commented Jan 30, 2025

It is irrelevant what was doing older version, only C standard is relevant.
If it is something in undefined behaviour no reason to change it, but if it is against standard then it is bug and must be fixed.

@alcz
Copy link

alcz commented Jan 30, 2025

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 ;-)

@alcz
Copy link

alcz commented Jan 30, 2025

Version 2.0 beta Feb 5 2020 06:09:49 (32-bit) here "OK"
current version #error's with BUG block uncommented

Older didn't truncate PP in this scenario either. We looked as far as Open Watcom C++ 12.70.8 (32-bit) on our hbtest for similar regression.

#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)

@jmalak
Copy link
Member

jmalak commented Jan 30, 2025

Sorry, but C++ compiler work with different standard C++98 I don't know how much it is different from C89 or C99.
Anyway try to use some expression, because we are talking about calculation in preprocessor not in C code.
Your case is only about macro definition and macro value, which should be OK.

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.

@alcz
Copy link

alcz commented Jan 30, 2025

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.

@omm omm changed the title 64bit expressions used in #[el]if statements in Win32 version 64bit expressions used in #[el]if statements Jan 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants