me: NAMESPACE: STRINGS: INIT: NULL: *issues*

General FreeBASIC programming questions.
cbruce
Posts: 164
Joined: Sep 12, 2007 19:13
Location: Dallas, Texas

me: NAMESPACE: STRINGS: INIT: NULL: *issues*

Post by cbruce »

.
Wondering if I am not comprehending everything about namespaces...

I'm ok with functions and #defines in namespaces... but DIM'ing strings and initializing them in there... also using NULLs in string initialization... and accessing any of those attempted strings outside the namespace... seems to be an issue for me.

Note: The real initialization literals are longer. I just cut them off for this test rig to get rid of the code wrapping.

See comments for issues:

Code: Select all

namespace test_ns
            '
    #define _NUL_ chr(0)
    #define _TAB_ chr(9)
    #define _LF_  chr(10)
    #define _CR_  chr(11)
    #define _SPC_ chr(32)
    #define _DQ_  chr(34)
    #define _SQ_  chr(39)
    #define _DEL_ chr(127)
            '
            ' NAMESPACE related Compiler Errors with STRING variables:
            '
            ' Variable define and initialize:
            ' 11: No strings will compile with a literal "chr(0)" in them.
            ' 87: Can't initialize a variable length string.
            '
            ' Variable use:
            ' 42: Strings that compile are not visible outside the namespace.
            '
            ' CONST
            ' ---------------------------------------
            ' _NUL_
            ' error 11: Expected constant, _WORD_BREAK_CHARS_ in 'const _WORD_BREAK_CHARS_ as String = _NUL_ ...
    'const _WORD_BREAK_CHARS_ as String = _NUL_ + _TAB_ + _LF_ + _CR_ + _SPC_ + "!" + _DQ_ + "#$%&" + _SQ_ 
            ' NO _NUL_
            ' Compiles - but not visible outside the namespace.
            ' error 42: Variable not declared, _WORD_BREAK_CHARS_ in 'print "len of ...
    'const _WORD_BREAK_CHARS_ as String = _TAB_ + _LF_ + _CR_ + _SPC_ + "!" + _DQ_ + "#$%&" + _SQ_
            '
            ' Variable length
            ' ---------------------------------------
            ' _NUL_
            ' error 87: Var-len strings cannot be initialized in 'dim _WORD_BREAK_CHARS_ as String = _NUL_ ...
    'dim _WORD_BREAK_CHARS_ as String = _NUL_ + _TAB_ + _LF_ + _CR_ + _SPC_ + "!" + _DQ_ + "#$%&" + _SQ_
            ' NO _NUL_
            ' error 87: Var-len strings cannot be initialized in 'dim _WORD_BREAK_CHARS_ as String = _NUL_ ...
    'dim _WORD_BREAK_CHARS_ as String = _TAB_ + _LF_ + _CR_ + _SPC_ + "!" + _DQ_ + "#$%&" + _SQ_
            '
            ' Fixed length
            ' ---------------------------------------
            ' _NUL_
            ' error 11: Expected constant in 'dim _WORD_BREAK_CHARS_ as String * 37 = _NUL_ ...
    'dim _WORD_BREAK_CHARS_ as String * 37 = _NUL_ + _TAB_ + _LF_ + _CR_ + _SPC_ + "!" + _DQ_ + "#$%&" + _SQ_
            ' NO _NUL_
            ' Compiles - but not visible outside the namespace.
            ' error 42: Variable not declared, _WORD_BREAK_CHARS_ in 'print "len of ...
    dim _WORD_BREAK_CHARS_ as String * 37 = _TAB_ + _LF_ + _CR_ + _SPC_ + "!" + _DQ_ + "#$%&" + _SQ_
            '
            ' Fixed length - SHARED
            ' ---------------------------------------
            ' _NUL_
            ' error 11: Expected constant in 'dim shared _WORD_BREAK_CHARS_ as String * 37 = _NUL_ ...
    'dim shared _WORD_BREAK_CHARS_ as String * 37 = _NUL_ + _TAB_ + _LF_ + _CR_ + _SPC_ + "!" + _DQ_ + "#$%&" + _SQ_
            ' NO _NUL_
            ' Compiles - but not visible outside the namespace.
            ' error 42: Variable not declared, _WORD_BREAK_CHARS_ in 'print "len of ...
    'dim shared _WORD_BREAK_CHARS_ as String * 37 = _TAB_ + _LF_ + _CR_ + _SPC_ + "!" + _DQ_ + "#$%&" + _SQ_
            '
end namespace

' Everything with a local DIM as CONST STRING works.
' Just a problem with defining and initializing STRINGs in namespace.
            '
'''dim _WORD_BREAK_CHARS_ as const String = _NUL_ + _TAB_ + _LF_ + _CR_ + _SPC_ + "!" + _DQ_ + "#$%&" + _SQ_
            '
print
print
print "outside namespace: len of _WORD_BREAK_CHARS_ = "; len( _WORD_BREAK_CHARS_)
'print "outside namespace: len of _WORD_BREAK_CHARS_ = "; len( test_ns._WORD_BREAK_CHARS_)
print
print
fxm
Moderator
Posts: 12106
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: me: NAMESPACE: STRINGS: INIT: NULL: *issues*

Post by fxm »

Code: Select all

print "outside namespace: len of _WORD_BREAK_CHARS_ = "; len( ( test_ns._WORD_BREAK_CHARS_ ) )
I will update the 3 documentation pages: Len, Sizeof, Typeof.


[edit]
Done.
Last edited by fxm on Jun 08, 2018 19:34, edited 1 time in total.
cbruce
Posts: 164
Joined: Sep 12, 2007 19:13
Location: Dallas, Texas

Re: me: NAMESPACE: STRINGS: INIT: NULL: *issues*

Post by cbruce »

Thanks fxm, but it wasn't just len(). When I tried to print the variable itself, or assign it to another variable, etc. The compiler gave that:

error 42: Variable not declared, _WORD_BREAK_CHARS_ in ... (whatever I was trying to use it for) ...

It could not see the variable defined in the namespace no matter what I did with it.

Are variables defined in namespaces only local to that namespace?
fxm
Moderator
Posts: 12106
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: me: NAMESPACE: STRINGS: INIT: NULL: *issues*

Post by fxm »

No problem for me:

Code: Select all

print test_ns._WORD_BREAK_CHARS_
or:

Code: Select all

using test_ns
'.....
print _WORD_BREAK_CHARS_
cbruce
Posts: 164
Joined: Sep 12, 2007 19:13
Location: Dallas, Texas

Re: me: NAMESPACE: STRINGS: INIT: NULL: *issues*

Post by cbruce »

Aargh!... Thanks! You are correct.

When I was first having problems defining the variables, I was using the namespace id when trying to print the variable itself. But I eventually just got down to using the PRINT LEN() that I showed in the test rig. So it's just the LEN() and associated functions.

EDIT: a note in NAMESPACE might be a good idea too.
cbruce
Posts: 164
Joined: Sep 12, 2007 19:13
Location: Dallas, Texas

Re: me: NAMESPACE: STRINGS: INIT: NULL: *issues*

Post by cbruce »

Also under NAMESPACE, the fact that it *requires* you to use the namespace identifier to access the namespace's variables.

EDIT: Plus the fact that... No strings in a namespace can be initialized with a NULL in the literal.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: me: NAMESPACE: STRINGS: INIT: NULL: *issues*

Post by MrSwiss »

cbruce wrote:Are variables defined in namespaces only local to that namespace?
By definition yes (sort of), however:
you can access them with: namespace-name.variable-name -- or --
use namespace-name (in main code) then
variable-name (exclusion: see below)

only true, if there is no name conflict, with a *local to main variable*
with identical name, then the first method is mandatory ...

For more info consult KeyPgNamespace in FB-Manual
cbruce
Posts: 164
Joined: Sep 12, 2007 19:13
Location: Dallas, Texas

Re: me: NAMESPACE: STRINGS: INIT: NULL: *issues*

Post by cbruce »

Thanks, MrSwiss. I only asked that question since I couldn't get the program to compile when I was trying to access the variable outside the namespace. But as fxm pointed out, it was just a problem with the LEN() function against the variable from the namespace.

I had poured over the manual (look at all of the different things I tried - [smile]). So it didn't make sense to me when it didn't work.
cbruce
Posts: 164
Joined: Sep 12, 2007 19:13
Location: Dallas, Texas

Re: me: NAMESPACE: STRINGS: INIT: NULL: *issues*

Post by cbruce »

.
Here's a summary for anyone that sees this thread...

EDIT: added #4.
EDIT: added nested parens to #3 thanks to sancho3 - (because I didn't catch it when fxm said it [smile]).
EDIT: added existing bug report reference to #3 thanks to fxm

' NAMESPACE related STRING variable issues:
'
' 1. Variable initialization strings in a namespace may
' *NOT* contain a NULL character. The compiler will
' either throw an error 11 or an error 87...
' depending on the type of string.

' 2. You *MUST* use the namespace identifier when
' accessing a namespace *variable* outside the
' namespace. Otherwise, the compiler will throw an
' error 42. You may do this explicitly...
' "namespace.var"
' ... or implicitly through "USING namespace".

' 3. Len, Sizeof, Typeof functions will not work on
' namespace defined variables *UNLESS* you nest the
' variable inside a second pair of parentheses...
' LEN( ( namespace.var) )
' ... *OR* if you use "USING namespace"
' Otherwise, the compiler will throw an error 42.
' ("fxm") There is an old bug report about this problem:
' #404 len/sizeof type parsing eats namespace prefix

' 4. Variable length strings may *NOT* be initialized
' in a namespace. The compiler will throw an
' error 42.
.
Last edited by cbruce on Jun 09, 2018 13:59, edited 4 times in total.
fxm
Moderator
Posts: 12106
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: me: NAMESPACE: STRINGS: INIT: NULL: *issues*

Post by fxm »

A variable declared inside a namespace is always implicitly static and visible throughout the entire program even if the declaration modifier Shared is not specified (static and shared are optional, but this may improve code readability).
So:

Code: Select all

Namespace NS
  Dim As String s
End Namespace
is implicitly equivalent to:

Code: Select all

Namespace NS
  Static Shared As String s
End Namespace
Therefore, any rules that affect static shared variables also affect any variables declared in a namespace.
sancho3
Posts: 358
Joined: Sep 30, 2017 3:22

Re: me: NAMESPACE: STRINGS: INIT: NULL: *issues*

Post by sancho3 »

@cbruce
Glad you got it sorted out. But #3 needs a little modification to make it more accurate:
3. Len, Sizeof, Typeof functions will work on namespace defined variable, but they need to be enclosed in parenthesis..
Otherwise, the compiler will throw an error 42. ex: print len( (mynamespace.myvar) )
There is also the fact that if you use 'using' the duplicate parenthesis are not necessary:

Code: Select all

Namespace test
	Static Shared As String * 3 m = "aaa"
End Namespace

Using test 
? Len(m)
Sleep 
That still leaves one thing not explained; why chr(0) cannot be used as a constant initializer.
The manual writes:
FreeBASIC evaluates the CHR function at compile time when used with constants or literals.

So chr(0) should also be evaluated, but it seems there is a special rule with regards to that.

Code: Select all

Const As String mytab = Chr(9)	' no problems
'Const As String mynul = Chr(0) 	' error 11, expected constant
Dim As String not_constant = Chr(0) 	' no problems
I have one more question: is there any difference between a static shared module level variable and a constant?
For a string I can see that the constant is stored as a zstring and a chr(0) appended.
For an integer are they handled the same by the compiler? Could you use either one without any differences?

Code: Select all

Const foo As String  = "aaa"
Static Shared As String * 3 m = "aaa"

Const moo As Integer = 12
Static Shared As Integer n = 12

#Print Typeof(foo)
#Print Typeof(m)
#Print Typeof(moo)
#Print Typeof(n)
cbruce
Posts: 164
Joined: Sep 12, 2007 19:13
Location: Dallas, Texas

Re: me: NAMESPACE: STRINGS: INIT: NULL: *issues*

Post by cbruce »

.
That's timely, sancho3... I was just typing a response to fxm about the CONST point when you posted...

Cool, fxm... I was able to do it with a CONST...

Code: Select all

const _WORD_BREAK_CHARS_ as String = _TAB_ + _LF_ + _CR_ + _SPC_ + "!" + _DQ_ + "#$%&" + _SQ_ + "()*+,-./:;<=>?@[\]^_`{|}~"
So my head was thinking that concatenated string was a constant value - and that I should be able to do that with a variable in the namespace also.
.
cbruce
Posts: 164
Joined: Sep 12, 2007 19:13
Location: Dallas, Texas

Re: me: NAMESPACE: STRINGS: INIT: NULL: *issues*

Post by cbruce »

.
Also, sancho3, I wonder if the chr(0) issue has to do with the fact that:
CONST
Specifying String as DataType is tolerated but without effect because the resulting type is always a Zstring * Size.

???
EDIT: Oops! - you basically already said that.
.
cbruce
Posts: 164
Joined: Sep 12, 2007 19:13
Location: Dallas, Texas

Re: me: NAMESPACE: STRINGS: INIT: NULL: *issues*

Post by cbruce »

sancho3, good catch on the nested parentheses. What made you think to try that? Is it documented somewhere to use it for this purpose?

EDIT: FYI - I edited the summary above to add the nested parens and USING information.
sancho3
Posts: 358
Joined: Sep 30, 2017 3:22

Re: me: NAMESPACE: STRINGS: INIT: NULL: *issues*

Post by sancho3 »

cbruce wrote:sancho3, good catch on the nested parentheses. What made you think to try that? Is it documented somewhere to use it for this purpose?
It was in FXM's first reply here. He gets the credit.
He just didn't articulate it.;)
Post Reply