News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

#IF

Started by Biterider, June 15, 2018, 06:29:57 AM

Previous topic - Next topic

Biterider

Hallo
I'm still working in the translation of header files to asm http://masm32.com/board/index.php?topic=6812.msg76894#msg76894.
ATM I have a working program that that converts tons of  files, which I'm checking now.
I found a problem with lines like this:
#if defined (_MSC_VER) && (_MSC_VER >= 1020)

The translation looks like
ifndef defined
  defined macro x
    ifdef x
      exitm <-1>
    else
      exitm <0>
    endif
  endm
endif

if defined(_MSC_VER) and (_MSC_VER ge 1020)


This code doesn't work in asm, since if _MSC_VER is not defined, the second condition is still checked producing a compilation error. This behavior is also present in ML, which I think is not correct.

Any chance to change that or to figure out a workaround?

Biterider

habran

instead of :if defined(_MSC_VER) and (_MSC_VER ge 1020)
it could be written as:
   if defined(_MSC_VER)
      if _MSC_VER ge 1020
           statement...
      endif
   endif

However, maybe someone comes with better idea.
Cod-Father

Biterider

Hi Habran
That's right. However, more complex statements that uses #elif or #else can not be written this way.
That is why I asked for support on your side.  ::)

As far as I can see, such a change should not brake existing code...

Biterider

jj2007

Workaround:
_MSC_VER=0  ; somewhere at the top of your source

... code that may set _MSC_VER ...

if _MSC_VER ge 1020
  ...

habran

I have tested the first version and it works as expected:
if defined(_MSC_VER) and (_MSC_VER ge 1020)

try to play with it.
I have used :

if defined(_MSC_VER) and (_MSC_VER ge 1020)
  .ERR <There is something wrong with that statement>
endif

and than tried this:

if defined(_MSC_KER) and (_MSC_VER ge 1020)  ; note _MSC_KER is fake
  .ERR <There is something wrong with that statement>
endif


so, in the second case it should throw an error but it doesn't

but with this it does throw an error:

if defined(_MSC_VER) and (_MSC_VER le 1020) ; note I have used le here
  .ERR <Tornero>
endif
Cod-Father

Biterider

Hi
@JJ: the windows header files is a house of cards that builds heavily upon the existence (definition) of symbols. If we define all of them, the result will not be the same, since we will include things we are not interested in. In case we do, we accept that all generated inc files will need to be corrected by hand (~2000 files for Win10)

@habran
I use the following test case

ifndef defined
  defined macro x
    ifdef x
      exitm <-1>
    else
      exitm <0>
    endif
  endm
endif

;Symbol equ 1

if defined(Symbol) and (Symbol eq 1)
  echo 1
else
  echo 2
endif



If Symbol is commened out, I get a compilation error (Error A2102: Symbol not defined : Symbol)

Biterider

habran

I can see now where is the problem ::)
I'll see what I can do about it ;)

However, it will take some time :dazzled:
Cod-Father

nidud

#7
deleted

Biterider

Hi nidud
There are hundreds of such cases in the header files. I chose the first one I found.
You're right with _MSC_VER, but I think there are cases where the undefined symbols are a problem.

Biterider

nidud

#9
deleted

habran

I agree with Biterider,
even if there are no undefined symbols in those headers it is obvious that assembler behaves inappropriate in such cases. 
Cod-Father

habran

The problem can be solved with definedmacro
it get computed: if 0 and (_MSC_KER le 1020)
Cod-Father

Biterider

Hi Habran
Can you be more explicit?


Thanks, Biterider

habran

defined macro returns 0 but it doesn't tell assembler not to continue.
In that case defined doesn't return a proper result.
if 0 and (_MSC_KER le 1020)
if 1 and (_MSC_KER le 1020)
these both cases will continue with AND
Cod-Father

habran

I have succeeded to prevent error for the case that symbol is not defined, it will work only with "if 0 and ...".
The fix is in expreval.c starting with line 1169:

                DebugMsg1(("get_operand(%s): symbol %s not defined, pass > 1, curr proc=>%s<, \n", tokenarray[i].string_ptr, tmp, CurrProc ? CurrProc->sym.name : "NULL" ));
                if ( opnd->type && *opnd->type->name ) {
                    fnEmitErr( MEMBER_NOT_DEFINED, opnd->type->name, tmp );
                } else {
                  if ((0 == _memicmp(tokenarray[0].tokpos, "if", 2)) &&
                      (0 == _memicmp(tokenarray[1].tokpos, "0", 1)) &&
                      (0 == _memicmp(tokenarray[2].tokpos, "and", 3)))
                    ;//skip it
                  else
                    fnEmitErr( SYMBOL_NOT_DEFINED, *(tmp+1) == '&' ? "@@" : tmp );
                }
                return( ERROR );
            }
#if ALIAS_IN_EXPR /* v2.04b: added */

the fix is:

                  if ((0 == _memicmp(tokenarray[0].tokpos, "if", 2)) &&
                      (0 == _memicmp(tokenarray[1].tokpos, "0", 1)) &&
                      (0 == _memicmp(tokenarray[2].tokpos, "and", 3)))
                    ;//skip it
                  else

It is an ugly hack but it works.
Let me know if you are happy with it.
If you can not build UASM I can post it here, because it looks like John is busy lately with his garden.
Cod-Father