Author Topic: MIN MAX  (Read 3675 times)

jcfuller

  • Sr. Member
  • ****
  • Posts: 394
    • View Profile
MIN MAX
« on: July 27, 2020, 05:53:38 AM »
Kevin,
  This may have been discussed in the past? It is a real concern in the José Afx adoption.
Thank you in advance for your consideration.

James


   Lines 8492 - 8498
        CASE "min"
        Stk$[Tmp] = "MIN"
        Use_Min = Use_Proto = TRUE

        CASE "max"
        Stk$[Tmp] = "MAX"
        Use_Max = Use_Proto = TRUE

change to :

        CASE "min"
          If UseCpp = FALSE Then
            Stk$[Tmp] = "MIN"
            Use_Min = Use_Proto = TRUE
          End If

        CASE "max"
          If UseCpp = FALSE Then
            Stk$[Tmp] = "MAX"
            Use_Max = Use_Proto = TRUE
          End If

jcfuller

  • Sr. Member
  • ****
  • Posts: 394
    • View Profile
Re: MIN MAX
« Reply #1 on: July 27, 2020, 06:15:48 AM »
CRAP
  I  should have tried it before I posted. BCX uses them in the compile.
But you do see the issue. I did have  working code in bc9. Now I need to track it down

James


jcfuller

  • Sr. Member
  • ****
  • Posts: 394
    • View Profile
Re: MIN MAX
« Reply #2 on: July 27, 2020, 08:05:18 AM »
Ok this may be a bit hard to follow. Most all changes to bc.bas are.
The original was obvious why it failed once I tried it. My bc.bas is translated to a c++ app
The next try was/is not clear why it failed. I assumed the __BCX___  would work and Use_Min/Max would not be set to TRUE?
The third I had done in bc9 not knowing about __BCX__ at the time
Why does the __BCX__ version fail??

James
   Lines 8492 - 8498
Code: [Select]

        CASE "min"
        Stk$[Tmp] = "MIN"
        Use_Min = Use_Proto = TRUE

        CASE "max"
        Stk$[Tmp] = "MAX"
        Use_Max = Use_Proto = TRUE

changed to :
Code: [Select]
        CASE "min"
          If UseCpp = FALSE Then
            Stk$[Tmp] = "MIN"
            Use_Min = Use_Proto = TRUE
          End If

        CASE "max"
          If UseCpp = FALSE Then
            Stk$[Tmp] = "MAX"
            Use_Max = Use_Proto = TRUE
          End If


failed when compiling bc.bas -> bc.cpp -> bc.exe

So I tried
Code: [Select]
        CASE "min"
          If (UseCpp = FALSE) OR (__BCX__ = 1) Then
            Stk$[Tmp] = "MIN"
            Use_Min = Use_Proto = TRUE
          End If

        CASE "max"
          If (UseCpp = FALSE) OR  (__BCX__ = 1) Then
            Stk$[Tmp] = "MAX"
            Use_Max = Use_Proto = TRUE
          End If

This also failed??
'==============================================================================

Then I went to the bc.bas main and added near the top
GLOBAL IsBc

Then (still in main) The line above : OPEN FileIn$  FOR INPUT  AS SourceFile
I added:
Code: [Select]
  If LCASE$(FileIn$) = "bc.bas" Then
IsBc = TRUE
  Else
     IsBc = FALSE
  End If

I then tried
Code: [Select]
        CASE "min"
          If (UseCpp = FALSE) OR IsBc Then
            Stk$[Tmp] = "MIN"
            Use_Min = Use_Proto = TRUE
          End If

        CASE "max"
          If (UseCpp = FALSE) OR  IsBc Then
            Stk$[Tmp] = "MAX"
            Use_Max = Use_Proto = TRUE
          End If

and it works. c++ sources use the build in c++  min/max macros, c  files and bc itself use the bcx MIN/MAX functions

James

MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 1885
    • View Profile
Re: MIN MAX
« Reply #3 on: July 27, 2020, 09:28:06 AM »
JC,

The past several versions of BCX have included 32 bit and 64 bit executables compiled with MSVC as c++ apps.

I understand that you don't want BCX to emit the MIN and MAX macros when emitting C++ code.  But that's not the whole story.  C++ uses lower case for min and max.  BCX's macros are UPPER CASE for a reason.

Another issue you are overlooking is that several BCX runtime functions use the macros MIN and MAX and would need more code added to BCX to conditionally emit the proper version (upper or lower case).
Things get complicated.  And then there's the matter of testing all those changes.

That's a fair amount of work that I'm not convinced is really needed. I'm going to need some proof
why the current system won't work with Jose's code when it seems to work just fine with everything else.

« Last Edit: July 27, 2020, 09:30:45 AM by MrBcx »

MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 1885
    • View Profile
Re: MIN MAX
« Reply #4 on: July 27, 2020, 09:51:41 AM »
Okay ... new idea, now that the caffeine is kicking in ...

Any reason why simply updating the MIN and MAX macros (shown below) wouldn't solve all the problems?


double MAX (double a_, double b_)
{
#if defined (__cplusplus)
return max(a_,b_);
#else
  if(a_ > b_)
  return a_;
  return b_;
#endif
}


double MIN (double a_, double b_)
{
#if defined (__cplusplus)
return max(a_,b_);
#else
  if(a_ < b_)
  return a_;
  return b_;
#endif
}

jcfuller

  • Sr. Member
  • ****
  • Posts: 394
    • View Profile
Re: MIN MAX
« Reply #5 on: July 27, 2020, 11:44:27 AM »
Kevin,
  Why have a BCX MIN/MAX at all. Pelles has it's own min/max macros;
Code: [Select]
Dim As int a,b
Dim As double d,dd
a = 7
b = 9
d= 14.7
! dd = max(a,d);
? dd
Pause

James

MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 1885
    • View Profile
Re: MIN MAX
« Reply #6 on: July 27, 2020, 12:08:32 PM »
Kevin,
  Why have a BCX MIN/MAX at all. Pelles has it's own min/max macros;
Code: [Select]
Dim As int a,b
Dim As double d,dd
a = 7
b = 9
d= 14.7
! dd = max(a,d);
? dd
Pause

James

A lot of stuff was created to provide compatibility with the list below.

Libraries have improved over time but not universally.

I don't have Watcom, Borland, or Digital Mars installed, so I can't test what effect your proposal would have on them.

I tested the ones in Green and Red.


Pelles C Compiler
MS Visual C/C++

Borland Free C++
Mingw32/64 C/C++
LLVM/Clang C/C++
Digital Mars C/C++
Open Watcom C/C++
LccWin32 C Compiler

Robert

  • Hero Member
  • *****
  • Posts: 1142
    • View Profile
Re: MIN MAX
« Reply #7 on: July 27, 2020, 12:13:37 PM »
I'm going to need some proof
why the current system won't work with Jose's code when it seems to work just fine with everything else.

Further to this comment, I can not find min or max used anywhere in the latest AfxWin.inc.

max was used in AfxSetWindowClientSize but no longer is it utilized in the latest version of  AfxWin.inc. In my adaption of AfxSetWindowClientSize for BCX, instead of using max, I at first used the following

Code: [Select]

    FPRINT FP_WRITE, "  long x = max((GetSystemMetrics(SM_CXSCREEN) - w) / 2, 0);"
    FPRINT FP_WRITE, "  long y = max((GetSystemMetrics(SM_CYSCREEN) - h) / 2, 0);"


but then found that the Embarcadero compilers did not have min/max, so, instead, I used this

Code: [Select]

    FPRINT FP_WRITE, "  long x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2;"
    FPRINT FP_WRITE, "  if(x<0 )"
    FPRINT FP_WRITE, "    {"
    FPRINT FP_WRITE, "     x=0;"
    FPRINT FP_WRITE, "    }"
    FPRINT FP_WRITE, "  long y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2;"
    FPRINT FP_WRITE, "  if(y<0 )"
    FPRINT FP_WRITE, "    {"
    FPRINT FP_WRITE, "     y=0;"
    FPRINT FP_WRITE, "    }"


I never did understand what the max was for but anyway Jose has thrown it out.

min max in C++ is a total P.I.A. because of the strict type checking.

I think it should be left up to the programmer to implement their own version of min/ max.

You wanna do it? Go ahead but keep your hands off my BCX. Don't you touch my MIN MAX !

Here's some hints for the C++ crowd.

Code: [Select]

inline
int min(int const x, int const y)
{
    return y < x ? y : x;
}

inline
unsigned minu(unsigned const x, unsigned const y)
{
    return y < x ? y : x;
}

inline
long minl(long const x, long const y)
{
    return y < x ? y : x;
}

inline
unsigned long minul(unsigned long const x, unsigned long const y)
{
    return y < x ? y : x;
}

inline
long long minll(long long const x, long long const y)
{
    return y < x ? y : x;
}

inline
unsigned long long minull(unsigned long long const x, unsigned long long const y)
{
    return y < x ? y : x;
}

inline
float minf(float const x, float const y)
{
    return y < x ? y : x;
}

inline
double mind(double const x, double const y)
{
    return y < x ? y : x;
}

inline
long double minld(long double const x, long double const y)
{
    return y < x ? y : x;
}

#define MIN(X, Y) (_Generic((X) + (Y),   \
    int:                min,             \
    unsigned:           minu,            \
    long:               minl,            \
    unsigned long:      minul,           \
    long long:          minll,           \
    unsigned long long: minull,          \
    float:              minf,            \
    double:             mind,            \
    long double:        minld)((X), (Y)))



« Last Edit: July 27, 2020, 12:15:41 PM by Robert »

jcfuller

  • Sr. Member
  • ****
  • Posts: 394
    • View Profile
Re: MIN MAX
« Reply #8 on: July 27, 2020, 12:34:50 PM »
  If Robert is writing a José Afx BCX port then never mind.
I mentioned mine was from 2016. Would be really nice for an updated version for BCX

James




Robert

  • Hero Member
  • *****
  • Posts: 1142
    • View Profile
Re: MIN MAX
« Reply #9 on: July 27, 2020, 01:06:41 PM »
  If Robert is writing a José Afx BCX port then never mind.
I mentioned mine was from 2016. Would be really nice for an updated version for BCX

James

Hi James:

The only thing that I did was modify Use_Form to size from the client window using code from  AfxSetWindowClientSize. Nothing else.

You can revisit the drama and its pathetic failure here.


https://bcxbasiccoders.com/smf/index.php?topic=66.msg238#msg238


Going forward, I still think that sizing from the client window is the best and most logical idea and for my programs I revise Use_Form whenever a new version of BCX is out.

I am going to have to restudy AfxSetWindowClientSize and adapt the improvements for Use_Form. And see if there is any effect on DPI changes.

Artists paint on the canvas, not the frame. Except for Banksy ...


MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 1885
    • View Profile
Re: MIN MAX
« Reply #10 on: July 27, 2020, 01:10:47 PM »

min max in C++ is a total P.I.A. because of the strict type checking.

I think it should be left up to the programmer to implement their own version of min/ max.

You wanna do it? Go ahead but keep your hands off my BCX. Don't you touch my MIN MAX !

Here's some hints for the C++ crowd.

Code: [Select]

inline
int min(int const x, int const y)
{
    return y < x ? y : x;
}

inline
unsigned minu(unsigned const x, unsigned const y)
{
    return y < x ? y : x;
}

inline
long minl(long const x, long const y)
{
    return y < x ? y : x;
}

inline
unsigned long minul(unsigned long const x, unsigned long const y)
{
    return y < x ? y : x;
}

inline
long long minll(long long const x, long long const y)
{
    return y < x ? y : x;
}

inline
unsigned long long minull(unsigned long long const x, unsigned long long const y)
{
    return y < x ? y : x;
}

inline
float minf(float const x, float const y)
{
    return y < x ? y : x;
}

inline
double mind(double const x, double const y)
{
    return y < x ? y : x;
}

inline
long double minld(long double const x, long double const y)
{
    return y < x ? y : x;
}

#define MIN(X, Y) (_Generic((X) + (Y),   \
    int:                min,             \
    unsigned:           minu,            \
    long:               minl,            \
    unsigned long:      minul,           \
    long long:          minll,           \
    unsigned long long: minull,          \
    float:              minf,            \
    double:             mind,            \
    long double:        minld)((X), (Y)))


That's quite an elaborate work-around for what should be a one line macro. 

  #define max(A, B) ((A) > (B) ? (A) : (B))   /* K&R The C Programming Language second edition.  */

I remember reading in K&R C Programming Language (1st edition), decades ago, about this simple concept called automatic type conversion.  "What happened?", he asked rhetorically ...
« Last Edit: July 30, 2020, 03:26:13 PM by MrBcx »

jcfuller

  • Sr. Member
  • ****
  • Posts: 394
    • View Profile
Re: MIN MAX
« Reply #11 on: July 27, 2020, 01:45:21 PM »

How about using a macro for MIN/MAX and then print both a min/max and  a MIN/MAX where needed. Just one extra line of code

#define max(a, b)  (((a) > (b)) ? (a) : (b))
#define MAX(a, b)  (((a) > (b)) ? (a) : (b))

James

jcfuller

  • Sr. Member
  • ****
  • Posts: 394
    • View Profile
Re: MIN MAX
« Reply #12 on: July 27, 2020, 02:45:02 PM »

That won't work you'll get a redefinition error

I just looked at a more recent José Afx and it has a mix of MAX and max ??

James

Robert

  • Hero Member
  • *****
  • Posts: 1142
    • View Profile
Re: MIN MAX
« Reply #13 on: July 27, 2020, 04:06:56 PM »

That won't work you'll get a redefinition error

I just looked at a more recent José Afx and it has a mix of MAX and max ??

James

Hi James:

Yes, you are correct. max is used in CWindow.inc. in lines 2139 and 2140,

I do not see a define for max in any of the Afx and FreeBASIC does not have a min/max. How does it work?

Is this your "real concern in the José Afx adoption" ? Do you use CTabPage.InsertPage often?

Are there other instances of max that I have missed?

I looked through the entire WinFBX download and only located

Code: [Select]
grep -nHIrF -- max( (in directory: /home/robert/Downloads/WinFBX-master)

./Afx/CWindow.inc:2139:   nWidth  = max(1, rc.Right - rc.Left)
./Afx/CWindow.inc:2140:   nHeight = max(1, rc.Bottom - rc.Top)

Search completed with 2 matches.

Robert

  • Hero Member
  • *****
  • Posts: 1142
    • View Profile
Re: MIN MAX
« Reply #14 on: July 27, 2020, 04:25:41 PM »

That won't work you'll get a redefinition error

I just looked at a more recent José Afx and it has a mix of MAX and max ??

James

Hi James:

C++ seems to be

__max

and

__min

in stdlib.h