Conflict between local/private String-name and TYPE def

General FreeBASIC programming questions.
MJK
Posts: 179
Joined: Nov 08, 2005 17:14
Location: Dublin, Ireland
Contact:

Conflict between local/private String-name and TYPE def

Post by MJK »

Folks,

Just got bitten with this fellow, and a few searches didn't throw it up... If a local string has the same name as a TYPE, then some elements of the TYPE definition apply - unexpectedly in my case ;-)

Here's a trivial demo:

Code: Select all

' Nasty problem with String handling (May, 2015)
' Checked with only FB 1.02.1, and under only Windows (Win7-64)

#include once "crt\win32\time.bi"       'Only to get at the "TM" structure (9 * LONGs, 36 bytes)

Sub Show_String()

    Dim as string  tm
    Dim as integer i

    tm = "123"

    Print "String/TYPE problem/bug.....": print
    Print "  TM: String =["; tm; "], expecting [123]."
    Print "  TM: Len(tm)="; Len(tm); ", expecting 3."
    Print

    If Len(tm) > 0 Then
        For i = 1 to len(tm)
            Print Hex(Asc(Mid(tm,i,1)),2);" ";
        Next i
        Print
    EndIf

End Sub

Show_String()
Print: Print "Done, Sleeping...";: Sleep: Print: Close: End
If lots of TYPE definitions are hanging around in the background, perhaps mostly unused, then simple code could be misbehaving!!

Should we/I post this as a "Bug" - assuming it has not been posted/resolved already?

Best regards,
- Mike
fxm
Moderator
Posts: 12159
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Conflict between local/private String-name and TYPE def

Post by fxm »

In that case of name conflict between type name and variable name, a workaround is to use double parentheses to access to those parameters of the variable, as:
Sizeof((x)), Len((x)), Typeof((x))

Code: Select all

' Nasty problem with String handling (May, 2015)
' Checked with only FB 1.02.1, and under only Windows (Win7-64)

#include once "crt\win32\time.bi"       'Only to get at the "TM" structure (9 * LONGs, 36 bytes)

Sub Show_String()

    Dim as string  tm
    Dim as integer i

    tm = "123"

    Print "String/TYPE problem/bug.....": print
    Print "  TM: String =["; tm; "], expecting [123]."
    Print "  TM: Len((tm))="; Len((tm)); ", expecting 3."
    Print

    If Len((tm)) > 0 Then
        For i = 1 to len((tm))
            Print Hex(Asc(Mid(tm,i,1)),2);" ";
        Next i
        Print
    EndIf

End Sub

Show_String()
Print: Print "Done, Sleeping...";: Sleep: Print: Close: End
MJK
Posts: 179
Joined: Nov 08, 2005 17:14
Location: Dublin, Ireland
Contact:

Re: Conflict between local/private String-name and TYPE def

Post by MJK »

Dang - I didn't know that "DOUBLE parentheses" were so significant! Thank you.

However, if a large program has a bunch of Includes, and they contain 50-100 miscellaneous TYPE defns, there's a possibility of an unintentional, very sneaky, conflict, so folks should be alert to this possibility. Perhaps general use of the LEN((xxx)) syntax should be recommended?

Thank you again,
- Mike
dkl
Site Admin
Posts: 3235
Joined: Jul 28, 2005 14:45
Location: Germany

Re: Conflict between local/private String-name and TYPE def

Post by dkl »

This is an annoying issue, that probably has bitten many people over the years. There were multiple discussions about changing the behaviour of len/sizeof, e.g. to only allow len() on strings and nothing else, or to make len() prefer variables instead of types, but those would all break existing code.

Then the remaining option was to add a warning if there is such ambiguity, an idea which I like quite a lot. Though it wasn't added yet. Maybe that's because the len/sizeof parsing code is a bit tricky due to the need to disambiguate types/expressions. I'm interested in working on this though.
fxm
Moderator
Posts: 12159
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Conflict between local/private String-name and TYPE def

Post by fxm »

Use of double parentheses forces the compiler to evaluate at first the expression.
Other tricks can be used as for example in your case:
Len(tm & "")
MJK
Posts: 179
Joined: Nov 08, 2005 17:14
Location: Dublin, Ireland
Contact:

Re: Conflict between local/private String-name and TYPE def

Post by MJK »

dkl wrote:This is an annoying issue, that probably has bitten many people over the years.
And, worse, it might remain undetected for a long time, and then bite!
Then the remaining option was to add a warning if there is such ambiguity, an idea which I like quite a lot. Though it wasn't added yet. Maybe that's because the len/sizeof parsing code is a bit tricky due to the need to disambiguate types/expressions. I'm interested in working on this though.
I think that's a superb suggestion. And then the programmer can adjust the code if needed, like using a non-duplicated var-name, or the double-parentheses, etc... I don't think I can help on such a mod, but if I can, I'll be very glad to do so.

- Mike
Boris the Old
Posts: 139
Joined: Feb 04, 2011 20:34
Location: Ontario, Canada

Re: Conflict between local/private String-name and TYPE def

Post by Boris the Old »

This may be a dumb question, but why doesn't the compiler apply its own scope rules?

Within a procedure, a local name should take precedence over a global name, so workarounds shouldn't be necessary.

Obviously a bug.

Rod
dkl
Site Admin
Posts: 3235
Joined: Jul 28, 2005 14:45
Location: Germany

Re: Conflict between local/private String-name and TYPE def

Post by dkl »

Well, it's complicated because FB allows a variable and a type with the same name in the same scope.

It was possible to add that feature probably because normally it's obvious whether you want a variable or a type, by looking at the context (used as an expression? => variable; used in a statement where a data type is expected? => type). Except in len/sizeof/typeof, which allows both kinds of symbols in the same place.
Boris the Old
Posts: 139
Joined: Feb 04, 2011 20:34
Location: Ontario, Canada

Re: Conflict between local/private String-name and TYPE def

Post by Boris the Old »

dkl wrote:Well, it's complicated because FB allows a variable and a type with the same name in the same scope.

It was possible to add that feature probably because normally it's obvious whether you want a variable or a type, by looking at the context.............Except in len/sizeof/typeof, which allows both kinds of symbols in the same place.
Unfortunately, this oversight has the potential for creating bugs that may not be detected for many years. This is a major design flaw that needs to be fixed. Asking FB programmers to use the double parentheses workaround is not a viable solution. Firstly, it now becomes the defacto syntax, since programmers must assume that all their variable and type names might be duplicated in library code. Secondly, in the future, this workaround may stop working if changes are made to the double parentheses feature.

If it were my decision, I'd force all names to be unique within a particular scope.This would not break much code, since variable names are most likely already unique and don't conflict with library code. It's certainly a better solution to have a few programmers change some variable names, than require everyone to use the workaround on the off-chance there might be a name conflict.

That's why we have compilers.

Rod
MJK
Posts: 179
Joined: Nov 08, 2005 17:14
Location: Dublin, Ireland
Contact:

Re: Conflict between local/private String-name and TYPE def

Post by MJK »

Boris the Old wrote:Secondly, in the future, this workaround may stop working if changes are made to the double parentheses feature.
Or, a new version of FB is released, where some Library definitions are extended, and a new TYPE is defined in there with a name that's already a local/private var-name in the app (with a few LEN()s, etc)..., and..... oopppssssss!....

- Mike
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Conflict between local/private String-name and TYPE def

Post by counting_pine »

The best thing I can think of is to have a way to explicitly give a type, and a way to explicitly give an expression (which we sort of already have); and have a warning if the compiler can't (easily) tell which it is, if it's implicit.
My suggestions for explicit type syntaxes would be:
- Angle brackets, e.g. len<T>, typeof<T>
- A keyword before the type name, maybe Type or As, e.g. sizeof(As T), typeof(Type T)
grindstone
Posts: 862
Joined: May 05, 2015 5:35
Location: Germany

Re: Conflict between local/private String-name and TYPE def

Post by grindstone »

I agree with Boris the Old. Using unique names would cause the least problems.

Regards
grindstone
MJK
Posts: 179
Joined: Nov 08, 2005 17:14
Location: Dublin, Ireland
Contact:

Re: Conflict between local/private String-name and TYPE def

Post by MJK »

counting_pine wrote:The best thing I can think of is to have a way to explicitly give a type, and a way to explicitly give an expression (which we sort of already have); and have a warning if the compiler can't (easily) tell which it is, if it's implicit.
My suggestions for explicit type syntaxes would be:
- Angle brackets, e.g. len<T>, typeof<T>
- A keyword before the type name, maybe Type or As, e.g. sizeof(As T), typeof(Type T)
[Hope all good with you!].

I think that a "confusion alert" message (perhaps only with "pedantic"?), and maybe an indication of which defn the compiler is using, would be a superb start!

Your suggestions on the explicit options also sound excellent to me, but I'm not familiar with the innards of FB, nor with the range of FB users/apps.

- Mike
dkl
Site Admin
Posts: 3235
Joined: Jul 28, 2005 14:45
Location: Germany

Re: Conflict between local/private String-name and TYPE def

Post by dkl »

A warning like this is working in Git now. At least it works for this case:

Code: Select all

type MSG
	i as integer
end type
dim msg as string
print len(msg)
... warning 37(1): Ambigious len(), referring to type MSG, instead of variable MSG
It doesn't work yet if there are namespaces involved:

Code: Select all

namespace ns
	type MSG
		i as integer
	end type
	dim msg as string
end namespace
print len(ns.msg)
Due to what is basically the same issue as in this bug:
len/​sizeof type parsing eats namespace prefix
MJK
Posts: 179
Joined: Nov 08, 2005 17:14
Location: Dublin, Ireland
Contact:

Re: Conflict between local/private String-name and TYPE def

Post by MJK »

Thank you for inserting these warnings, and for the update notes here. Those "warnings" seem excellent to me.

I don't recall every compiling FB from the GIT. so I located the WIKI notes on how to download the latest sources, and MinGW, some LIBs, etc. I followed these notes very closely (I think!), and got a new FBC.EXE, but the MAKE always bombed on a subsequent GCC step. I did not use the default foldernames that are mentioned in the notes, and this may be the root of my problem, but I'm not sure. So, I probably won't be able to play with these new warnings until the next full release of FB.

Thank you again for these updates.
- Mike
Post Reply