Setting based 1 Arrays

  • Thread starter Thread starter Mike
  • Start date Start date
Michael C said:
Really? Some areas of vb6 and zero based and some are 1 based. I'm not
sure how that's my fault mike :-)

Interestingly this has never been a problem for me. I wonder how other
developers are able to write useful programs if different lower array
boundaries pose a problem.
 
Cor Ligthert said:
Is it not a good idea to explicit add to the code "For VB6" for VB6 or any
other not Net tool as it not is for dotNet.vb as you write something for
VB6 in this newsgroup?

This newsgroup has dotNet in its name, therefore before somebody searching
for solutions and find this in a dotNet newsgroup can make wrong
conclusions

I don't think this is a huge problem if the reader has 'Option Brain On'
enabled. It's pretty clear that the discussion went into the direction of a
comparison between VB6 and VB.NET regarding array boundaries.
 
Mike said:
For our VB.NET port, and for the sake of some level of USAGE
compatibility, I want (desire) to maintain the long traditional idea for
BASIC programmers that these fields are based one. We also have an
server-side embedded BASIC language that are based 1 as well. So it would
help to maintain this concept.

Unfortunately the functionality is not exposed by the syntax of VB.NET. You
can, however, create 1-based arrays at runtime:

\\\
Dim x As Array = _
Array.CreateInstance( _
GetType(String), _
New Integer() {10}, _
New Integer() {1} _
)
MsgBox(x.GetLowerBound(0))
///

Again, unfortunately the array object created by the code above is not of
type 'String()', so it's not possible to use the array directly in the way
it's possible with "normal" arrays in VB.NET.
 
Herfried said:
[...]
Again, unfortunately the array object created by the code above is
not of type 'String()', so it's not possible to use the array
directly in the way it's possible with "normal" arrays in VB.NET.

Similar to the first answer in this (admittedly long) thread. ;-)


Armin
 
Unfortunately the functionality is not exposed by the syntax of VB.NET. You
can, however, create 1-based arrays at runtime:

\\\
Dim x As Array = _
Array.CreateInstance( _
GetType(String), _
New Integer() {10}, _
New Integer() {1} _
)
MsgBox(x.GetLowerBound(0))
///

Again, unfortunately the array object created by the code above is not of
type 'String()', so it's not possible to use the array directly in the way
it's possible with "normal" arrays in VB.NET.

This is an unfortunate compiler implementation. Which is to bad. As can be
seen in a codes sample I posted earlier, you can cast the array to a typed
array - as long as it has more then one dimmension.
 
Tom said:
It's not random at all.... And it's very clear:

Arrays: If the lower bound is not explicitly delcared, then the lower bound
will be the value of Option Base. If Option Base is not explicitly set, then
it defaults to Option Base 0.

Strings: They start at one. Strings are not arrays in VB6 - and the functions
that work on strings start at one.

I personally never really used arrays that didn't start at 0, BUT - this is a
feature that should NOT have been removed from VB. This is one of the few
items where change was made for changes sake - especially since .NET arrays
clearly support non-zero bounds.

It does seem very odd that MS decided to do this for VB.NET given
that, in my view, VB is that help keep MS in the higher level GUI
application development in corporations. C/C++ was more for system
developers. I mean, it was freaking the Killer App "Visual BASIC"
that finally allow them to move on from OS/2 and the IBM partnership.

I am also surprise they did away with VARIANT - isn't this a
fundamental part of OLE automation?

But I do find the "mixed" language interesting. C++ string
concatenation is supported:

Dim s as string = ""
s += "Hello"
s += " "
s += "Tom"

I mean, they did this, but didn't bother to add // or /* */ commenting
or do away with the need to use _ for continuation lines :-)

I mean, if you are going to fundamentally force a HUGE market of VBers
to think differently, then go ahead and add the other C/C++ language
goodies.

Anyway, this seemed like a case where the VB "champions" at MS were
not invited to the design review meeting full of these "Young .NET
punks" who had the card blanc with .NET. They had the final or greater
say. :-)

I can understand the decision somewhat, but I think it was
hypocritical in many ways. At the very least, they should of made it
an compiler option and/or maintain the OPTION BASE X option.

What I find most surprising is that after all these years, it (among
other things) appears to be still a sore issue.

PS: I did not wish this to become a rude war among what appears to be
long time participant friends here :-)

--
 
Tom said:
If your interested in seeing examples of using .NET code from C++ or creating
.NET libraries that wrap C++ code, I do have a couple articles on my blog that
cover some of the basics of this: www.tom-shelton.net

One article covers creating a C++/CLI wrapper around a lib file so that you can call
the code directly from a .NET app.

Thanks Tom. I will definitely look over your work.

Before I dropped dead this morning, I did finally got three
WcServerAPI class libraries in VB.NET, C# and C++/CLR. I wanted to
see how different language applications can reference/link either one in.

The last one I went as far for a proof of concept by importing the lib
and wrapping and exposing one of the functions in a class:

// WcServerAPICLR.h

#pragma once

#include <windows.h>

// Wildcat! SDK header and DLL library
#include <wcserver.h>
#pragma comment(lib,"wcsrv2.lib")
//

using namespace System;

namespace WcServerAPICLR {
public ref class Wildcat
{
public:
static boolean WildcatServerConnectLocal(int parent)
{
return ::WildcatServerConnectLocal((HWND)parent);
}
};
}

and with this I noticed the closeness of the methods with COM+ IDL
declarations. i.e, the class interface wizard uses primitive return
and parameter types and I think I will need to use HRESULT to return
more complex types.

Off hand, I am back to square one. For anything outside native
compiler types, going to classes for types means it only pertain for
either VB.NET or not.

The fact(?) VARIANT was removed in all the .NET languages it seems,
makes this a little harder. I thought that was going to be the
commonality between all the languages.

I see there is a VariantType, VariantWrapper class. Going to google
this now :-)

--
 
Herfried K. Wagner said:
In C# everything is in a way that does not feel natural to the human ;-).

That depends on the human. I agree 1 based is more natural to humans but
neither vb.net or c# are 1 based.
Personally I prefer the '0 To x' syntax for arrays

If you did a survey of all programmers across all languages you'd find that
to be extremely unpopular. You might find it popular among VBers which would
indicate they only like it because that is what they are used to. To have
the array 1 bigger than x is really not a good thing. The method where
specify the count is much better because that is all you need to specify,
you don't need to specify a lower bound.
and I'd really appreciate custom array boundaries (not for collections,
but for arrays).

In 20+ years of programming I'm yet to find a need for specifying a custom
array lower bound. It's is quite simply not necessary.

Michael
 
Tom Shelton said:
It's not random at all.... And it's very clear:

When I say random, I mean the decisions the VB design team made at the time
appear to be random. They chose zero based default for arrays, 1 based for
string functions, and a combination of zero and 1 based for other components
seemingly at random. The arrays show their idecision further with this
option base rubbish.
Arrays: If the lower bound is not explicitly delcared, then the lower
bound
will be the value of Option Base. If Option Base is not explicitly set,
then
it defaults to Option Base 0.

Strings: They start at one. Strings are not arrays in VB6 - and the
functions
that work on strings start at one.

Yes I know all that, I stated all this already.
I personally never really used arrays that didn't start at 0, BUT - this
is a
feature that should NOT have been removed from VB. This is one of the few
items where change was made for changes sake - especially since .NET
arrays
clearly support non-zero bounds.

I'm quite happy for it to be removed, I think the mistake was supporting
non-zero bounds (surely this must slow things down slightly?). An array is a
list of items starting at position 0 and incrementing. The position is not
meant to incorporate any further data besides being a position.

Michael
 
Michael Williams said:
It is NOT random, and it is NOT documented as being random, and you are an
idiot for saying so.

Same thing I said to Tom, when I say random Mike I mean the decisions made
by the VB design team appear to be random. They chose base 0 in some areas
and 1 based in others. There appears to be no logic behind their desicions.
Wrong! The base of arrays in VB6 is determined by your code. The base can
be zero or 1 or just about any other integer you desire, depending on your
personal choice. It is all very clearly documented and is very definitely
NOT random.

Ok ok mike don't have a heart attack. I meant the default for arrays is zero
based.
You are wrong when you say that arrays are zero based and you are wrong
when you say that the base is random. How many other things would you like
to be wrong on?

So basically I'm not wrong because you have simply misunderstood me on both
these items. I'm a little suprised you actually thought that I thought the
base of an array was random.
Yes, Mid and Left and Right and Instr and other string handling functions
count the first character of a string as being character number one. It is
definitely NOT random.

I never said it was random, I said the decision to make it 1 based appears
to be random.
Of course I am able to do that! How much do you want? Here is an extract
taken verbatim from the help files. If you want any more then you'll have
to drag yourself out of your lazy stupor and find it yourself:

Option Base Statement. Used at module level to declare the default
lower bound for array subscripts.
Syntax: Option Base {0 | 1}
Remarks: Because the default base is 0, the Option Base statement
is never required. If used, the statement must appear in a module
before any procedures. Option Base can appear only once in a
module and must precede array declarations that include dimensions.
Note: The To clause in the Dim, Private, Public, ReDim, and Static
statements provides a more flexible way to control the range of an
array's subscripts. However, if you don't explicitly set the lower
bound with a To clause, you can use Option Base to change the
default lower bound to 1.

But where in the VB documentation does it say that VB is zero based or 1
based?

Michael
 
Herfried K. Wagner said:
Interestingly this has never been a problem for me. I wonder how other
developers are able to write useful programs if different lower array
boundaries pose a problem.

I managed to survive and make programs that people liked but that is not the
point. VB6 was a pita with regards to it's 0 and 1 based rubbish. Having
something consistant and aligned with the rest of the industry is a good
thing.

Michael
 
Mike said:
and with this I noticed the closeness of the methods with COM+ IDL
declarations. i.e, the class interface wizard uses primitive return and
parameter types and I think I will need to use HRESULT to return more
complex types.

Off hand, I am back to square one. For anything outside native compiler
types, going to classes for types means it only pertain for either VB.NET
or not.

The fact(?) VARIANT was removed in all the .NET languages it seems, makes
this a little harder. I thought that was going to be the commonality
between all the languages.

I see there is a VariantType, VariantWrapper class. Going to google this
now :-)

They renamed variant to Object (or object in C++). Although you should be
able to return your wrapper classes no problem.

Michael
 
Michael C said:
I'm quite happy for it to be removed, I think the mistake was supporting
non-zero bounds (surely this must slow things down slightly?). An array is
a list of items starting at position 0 and incrementing. The position is
not meant to incorporate any further data besides being a position.

At least for me an array index is more than a position only. In addition, I
consider it a numeric /key/ used to define a mapping between numeric keys
and values (f(x) = y, x in [a, ..., b]).

However, almost no programming language/framework is drawing a clear line
between arrays and different types of collections, and array support built
directly into the languages is often rather limited.
 
Herfried K. Wagner said:
At least for me an array index is more than a position only. In addition,
I consider it a numeric /key/ used to define a mapping between numeric
keys and values (f(x) = y, x in [a, ..., b]).

An array is meant to be the simplest most efficient list you can have, a
contiguous block of memory. You should not be able to add an item and you
should not be able to insert an item. Changing an item is ok. These
limitation are based around the limitations of the computer hardware and
should be reflected back to the user of the high level language. To allow
users to resize arrays just muddies the water between array and collection.

If you want to add, insert, remove items or store a key then you don't want
an array, you want a collection of some sort.
However, almost no programming language/framework is drawing a clear line
between arrays and different types of collections,

It is a lot clearer in C# than VB. In C# you cannot modify your array making
it pretty obvious to the programmer it is a fixed block of memory. If you
want a fixed block that does not change then use an array, if you need to
change it then use a collection.
and array support built directly into the languages is often rather
limited.

What do you mean there?

Michael
 
Michael said:
They renamed variant to Object (or object in C++).

I think you mean replaced :-)
Although you should be able to return your wrapper classes no problem.

I was able to get an equivalent function GetAccessProgramNames() to
return a string array in C++:

namespace WcServerAPICLR {

public ref class Wildcat
{
public:
...
static int GetAccessProfileCount()
{
return ::GetAccessProfileCount();
}
static array<String^>^ GetAccessProfileNames()
{
array<String^>^ alist = {};
int count = wcat::GetAccessProfileCount();
TSecurityName *names = new TSecurityName[count];
if (::GetAccessProfileNames(count, names)) {
alist = gcnew array<String^>(count);
for (int i=0; i < count; i++) {
alist = gcnew String(names);
}
}
delete []names;
return alist;
}
};
}

Usage in vb.net application:

Dim alist As String() = GetAccessProfileNames()
Console.WriteLine("alist size: {0}", alist.Length())
For Each s As String In alist
Console.WriteLine("- [{0}]", s.ToString)
Next

Programming was suppose to get EASIER, not harder. :-)

--
 
Michael D. Ober said:
The statement

dim Security(NUM_USER_SECURITY) as string

will create an array with the lower bound 0 and upper bound
NUM_USER_SECURITY. You can then treat the array as if it were 1 based as
in

for i = 1 to NUM_USER_SECURITY
debug.print(Security(i))
next i

That's not really a good way to do things. You end up with the case where
Security(0) = "ABC" does not produce an error.
VB.net does this for just the issue you are referring to.

I thought the only reason it did this was for an illusion of compatibility
with vb classic.

Michael
 
Michael Williams said:
It is NOT random, and it is NOT documented as being random, and you are an
idiot for saying so.


Wrong! The base of arrays in VB6 is determined by your code. The base can
be zero or 1 or just about any other integer you desire, depending on your
personal choice. It is all very clearly documented and is very definitely
NOT random.


You are wrong when you say that arrays are zero based and you are wrong
when you say that the base is random. How many other things would you like
to be wrong on?


Yes, Mid and Left and Right and Instr and other string handling functions
count the first character of a string as being character number one. It is
definitely NOT random.


That statement of yours is ill thought out and illogical and completely
wrong. You obviously do not understand the meaning of the word random.
Perhaps you should look it up in your favourite dictionary. The fact that
the Mid function and other string functions count the first character of a
string as being character number 1 whereas the base of an array is as
determined by the programmer and otherwise defaults to zero does NOT make
either of those things random. Having the facility to specify the base of
an array yourself is sometimes quite useful and often enables you to
visualise things more easily for certain specific tasks, but if you would
prefer to always have all your arrays zero based then you can do so. It is
up to the programmer, and it is very clearly documented. It is NOT random.


Of course I am able to do that! How much do you want? Here is an extract
taken verbatim from the help files. If you want any more then you'll have
to drag yourself out of your lazy stupor and find it yourself:

Option Base Statement. Used at module level to declare the default
lower bound for array subscripts.
Syntax: Option Base {0 | 1}
Remarks: Because the default base is 0, the Option Base statement
is never required. If used, the statement must appear in a module
before any procedures. Option Base can appear only once in a
module and must precede array declarations that include dimensions.
Note: The To clause in the Dim, Private, Public, ReDim, and Static
statements provides a more flexible way to control the range of an
array's subscripts. However, if you don't explicitly set the lower
bound with a To clause, you can use Option Base to change the
default lower bound to 1.

Mike
Speaking of idiots, it is fairly appearent that we can all aspire to that
state form time to time. You, however, seem to be persuing a masters in the
subject.
 
Michael said:
Absolutely. But are you creating this dll in C++.net or VB.net?

Michael

Well, I have created the DLL in all three languages. VB.NET, C# using
the modules (http://www.winserver.com/public/wcsdk) and a stub in C++
using a few functions.

I am no longer sure if using the C++ class library is the way to go
because as far as I can see, it is much more complex using the new C++
CLR language. So much is hidden and you have to wrap (marshall) all
the function IN/OUT anyway.

At least with DLLImport and UmmanagedType attributes you can tell the
compiler exactly what you want.

I was getting further with VB.NET class library and the DLL supports
the other languages too.

I just don't get why MS has made all these so complex. Wrapper after
wrapper after wrapper and wrapper for freaking everything :-)

--
 
Mike said:
Well, I have created the DLL in all three languages. VB.NET, C# using the
modules (http://www.winserver.com/public/wcsdk) and a stub in C++ using a
few functions.

I am no longer sure if using the C++ class library is the way to go
because as far as I can see, it is much more complex using the new C++ CLR
language. So much is hidden and you have to wrap (marshall) all the
function IN/OUT anyway.

At least with DLLImport and UmmanagedType attributes you can tell the
compiler exactly what you want.

I was getting further with VB.NET class library and the DLL supports the
other languages too.

I just don't get why MS has made all these so complex. Wrapper after
wrapper after wrapper and wrapper for freaking everything :-)

I can't help with the C++ side but I wouldn't have thought it would be that
many wrappers :-) I guess vb.net or C# will be easier.

Michael
 
Back
Top