Menu

#718 Using "len" throws error 7 when used with variables with the same name as their (or other) types

closed
nobody
None
compiler
2019-12-07
2014-01-29
glagnar
No

This may happen in other situations, but I'm not sure. It looks like len evaluates the first possible symbol before checking if further resolution is possible.

Surrounding the variable name with parentheses works around the issue.

If no fix is possible, a different warning may be reasonable: "Ambiguous meaning of 'symbol'" perhaps?

type TEST
    as string SomeString
end type

dim as TEST Test
Test.SomeString = "abcdef"
if len(Test.SomeString) > 0 then
   ' Above line will raise error 7 (expected ')', found '.')
end if

if len((Test).SomeString) > 0 then
   ' Above line does not raise an error
end if

Related

Feature Requests: #293

Discussion

  • dkl

    dkl - 2014-01-29

    This looks familiar. The tokens given inside the len() are parsed as type first, then as expression later. That means it prefers the type over a variable with the same name.

    In general this makes sense for sizeof(), but for len() it can be confusing due to its double meaning ("sizeof" or "string length"). I don't know why but that's how it was implemented. Changing it now would be very risky because it could cause old code to be silently miscompiled.

    In this case though where there's a field access following there should perhaps be better disambiguation... however, I think the reason that it behaves the way it does at the moment is to allow accessing namespaced types. I.e., it prefers namespace.type over variable.field. Here the UDT is the namespace, that's because it contains a string which makes it a "class". But I'm sure that the disambiguation here could be improved at least for some cases if not all, to avoid the expected ')' error.

    There's a closely related issue coming into play though, which needs to be fixed first, see also [#404]. Any namespace prefix eaten by the type parser is not reparsed by the expression parser, instead it is just lost (which is a bug).

     

    Related

    Bugs: #404

  • Jeff Marshall

    Jeff Marshall - 2019-12-07

    Not just len/sizeof, but in general, syntax that should not be allowed:

    type T
        i as integer
        s as string
    end type
    
    print T.i
    print T.s
    

    Deep inside hFindId we see T.i and T.s being allowed as expression even though there is no instance parameter. Either we need to find a way to raise the error at the time of lexing/parsing, or allow the expression to be parsed fully and then raise the error based on where it might be use, because in the case of constants, this syntax is OK.

     
  • Jeff Marshall

    Jeff Marshall - 2019-12-07
    • status: open --> closed
     
  • Jeff Marshall

    Jeff Marshall - 2019-12-07

    Fixed in [6f5401]

     

    Related

    Commit: [6f5401]

  • Jeff Marshall

    Jeff Marshall - 2019-12-07

    Related (but not quite same bug) in [bugs:#919]

     

    Related

    Bugs: #919


Log in to post a comment.