Board index » cppbuilder » AnsiString , StringList 's AnsiString question

AnsiString , StringList 's AnsiString question

I'm sure someone else can give you a more technical explanation, but
the fact is that an AnsiString is an instance of a class, not a memory
address to be dereferenced.  It's just plain wrong to think of the
variable name as an allocated memory address.  That applies even more
to a TStringList.  You should not be "able" to write into the middle
of a complex component;  You should have to ask the Methods of the
object to make changes for you.  It's a fact that you can use the
property myStringList->Strings->Text to tamper with all the strings at
once.  Perhaps that property should not have been exposed, because you
could destroy the object that way...  A comparable issue would be how
in various versions of BCB it has and has not been possible to *set*
one character in an AnsiString with the [] operator:  myStr[i]='a';  A
more advanced topic (not related to your current testing) is that
copies of AnsiStrings are reference counted.

--
Timothy H. Buchman
========================================
City Center Theater
New York NY
tbuchmanREMOVE@NO_SPAMcitycenter.org
Please treat this signature information as confidential.
========================================
Search .borland newsgroup archives at:
http://www.mers.com/searchsite.html

slave of linux <wm...@ksts.seed.net.tw> wrote in message
news:8rm2oa$hm18@bornews.borland.com...

Quote
> Hi all,

> I did a test and found that after execute the method 'test'
> 'AnsiString a' become 'test success' , however 'TstringList str'
> str->Strings[0] still not changed. WHY ?
> Both of they are AnsiString , but why there are different result ?

 

Re:AnsiString , StringList 's AnsiString question


Hi all,

I did a test and found that after execute the method 'test'
'AnsiString a' become 'test success' , however 'TstringList str'
str->Strings[0] still not changed. WHY ?
Both of they are AnsiString , but why there are different result ?

the codes are below :

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    TStringList *str = new TStringList();
    AnsiString a ;

    str->Add("this is a test");
    a = "this is test2";

    test( &(str->Strings[0]) );
    test( &a );

    delete str;

Quote
}

void __fastcall TForm1::test(AnsiString *p)
{
    *p = "test success!!";
Quote
}

Re:AnsiString , StringList 's AnsiString question


I am very agreed your opinion,but
the property Strings of TStringList is Read/Writeable .
So, why cannot we  use it directly?

Timothy H. Buchman <tbuch...@citycenter.org> wrote in message news:39de9ea7$1_1@dnews...

Quote
> I'm sure someone else can give you a more technical explanation, but
> the fact is that an AnsiString is an instance of a class, not a memory
> address to be dereferenced.  It's just plain wrong to think of the
> variable name as an allocated memory address.  That applies even more
> to a TStringList.  You should not be "able" to write into the middle
> of a complex component;  You should have to ask the Methods of the
> object to make changes for you.  It's a fact that you can use the
> property myStringList->Strings->Text to tamper with all the strings at
> once.  Perhaps that property should not have been exposed, because you
> could destroy the object that way...  A comparable issue would be how
> in various versions of BCB it has and has not been possible to *set*
> one character in an AnsiString with the [] operator:  myStr[i]='a';  A
> more advanced topic (not related to your current testing) is that
> copies of AnsiStrings are reference counted.

> --
> Timothy H. Buchman
> ========================================
> City Center Theater
> New York NY
> tbuchmanREMOVE@NO_SPAMcitycenter.org
> Please treat this signature information as confidential.
> ========================================
> Search .borland newsgroup archives at:
> http://www.mers.com/searchsite.html

> slave of linux <wm...@ksts.seed.net.tw> wrote in message
> news:8rm2oa$hm18@bornews.borland.com...
> > Hi all,

> > I did a test and found that after execute the method 'test'
> > 'AnsiString a' become 'test success' , however 'TstringList str'
> > str->Strings[0] still not changed. WHY ?
> > Both of they are AnsiString , but why there are different result ?

Re:AnsiString , StringList 's AnsiString question


"slave of linux" <wm...@ksts.seed.net.tw> wrote in message
news:8rm2oa$hm18@bornews.borland.com...

Quote
> I did a test and found that after execute the method 'test'
> 'AnsiString a' become 'test success' , however 'TstringList str'
> str->Strings[0] still not changed. WHY ?

This is an old trap that fools many people the first time they use the VCL.
Your problem is that Strings[0] is not a member variable, but rather a
property.  In order to make things 'look' simple properties have been given
a syntax to look like variables, however they do not behave like them 100%
as you have just discovered.  Personally, I find this (potentially)
confusing and avoid creating properties in my own code for that very reason.
The exception to this rule is when creating components, where you need
properties to appear in the object inspector.  This was the original purpose
they were designed for, and a job they do well, but I digress...

Quote
>     test( &(str->Strings[0]) );
>     test( &a );

What you are doing here is passing the pointer to a string.  Given that a is
a local variable, this will do what you expect.  However, Strings[0] is a
property, and the result is a temporary string returned by a function call.
I would not expect changing the result of a function to have any affect on
the data used by the function itself! Unless the function returned a
reference, which in this case it doesn't.  Why not?  Well, the idea of a
property is to wrap acces with functions to allow side-effects
(TForm::Width, for instance) and enforce consistency.  Letting you change
the internal value without going through the set function would skip all
that, with would be a 'bad thing'TM.

Quote
> void __fastcall TForm1::test(AnsiString *p)
> {
>     *p = "test success!!";
> }

However, I am dissappointed if calling this with the property-pointer did
not generate a warning.  All temporary values returned from functions are
treated by the compiler as being declared 'const' so there should have been
a warning about passing a cont-pointer to a non-const parameter.  If you had
such a warning and didn't understand what it was talking about, now you
know.  Otherwise, Borland need a bug-report!

AlisdairM

Re:AnsiString , StringList 's AnsiString question


"Timothy H. Buchman" <tbuch...@citycenter.org> wrote in message
news:39de9ea7$1_1@dnews...

I think you misunderstand a few points, although it could just be I disagree
with the way you are explaining things.  I'll try to clarify each point...

Quote
> I'm sure someone else can give you a more technical explanation, but
> the fact is that an AnsiString is an instance of a class, not a memory
> address to be dereferenced.

Which should make no difference when passed by pointer though.

Quote
> You should not be "able" to write into the middle of a complex
> component;

This is good design, making all your member data private.   However, you
make member data public there is nothing in the language to stop you doing
this, and is in fact exactly the sort of abuse you are inviting!

Quote
> You should have to ask the Methods of the
> object to make changes for you.

Hear hear! :? )

Quote
>  It's a fact that you can use the
> property myStringList->Strings->Text to tamper with all the strings at
> once.  Perhaps that property should not have been exposed, because you
> could destroy the object that way...

In what way could you destroy the object?  Text is simply another property
with read and write methods.  When you write to the Text property the list
is appropriately updated.  If you write rubbish, of couse you can make a
mess of your list, but at least it will be a valid, consistent mess!  You
can just as easily add rubbish to the list via the Add method, I don't want
my compiler second guessing what my data is supppod to mean and correcting
it for me!

Quote
> A comparable issue would be how
> in various versions of BCB it has and has not been possible to *set*
> one character in an AnsiString with the [] operator:  myStr[i]='a';

Which versions were those?  As far as I am aware this has always been
possible, as one of the basic uses of the class.  What you haven't been able
to do is change a single character in a string *property* this way, because
you are acting on the return value of the GetText function (or whatever) not
the internal representation of the string.  There is nothing to call back
the property SetText function.

You might want to take another look at how properties are implemented, and
how they simulated variables without actually being variables.  In
particular, look into what they should not be expected to do that you would
expect from a variable.

AlisdairM

Re:AnsiString , StringList 's AnsiString question


Thanks very much for your comments.  Although I have a BCB3 version
that includes source code, I don't have time to study it; I just
assume that the components will behave as advertised.  Of course,
that's occasionally a disappointment...

While researching your comments, I found the answer to slave to linux'
question.  The Strings property of TStringList returns a temporary, so
the object itself cannot be modified.  This fixed a bug in BCB3
regarding use of the [] operator.  This is discussed at

http://x67.deja.com/[ST_rn=fs]/getdoc.xp?AN=451688055&search=thread&CO
NTEXT=970943145.1150812187&HIT_CONTEXT=970942453.1143406593&HIT_NUM=32
&hitnum=1

(Sorry, MERS site is down today.  That link above is next to useless.
It's Jody Hagins 03/05/99 cppbuilder.language)

Quote
Alisdair Meredith <wrong.pc.today> wrote in message

news:39decf97_1@dnews...
Quote
> >  It's a fact that you can use the
> > property myStringList->Strings->Text to tamper with all the
strings at
> > once.  Perhaps that property should not have been exposed, because
you
> > could destroy the object that way...

> In what way could you destroy the object?  Text is simply another
property
> with read and write methods.  When you write to the Text property
the list
> is appropriately updated.  If you write rubbish, of couse you can

make a

I have (perhaps incorrectly) assumed that if you added /r or /n
characters to the Text property of a TStringList that you would then
have *incorrect* properties like Count, and that perhaps the Objects
would no longer be associated with the correct String.  I would be
pleased to hear that I'm wrong about that.  One reason I assumed that
is that I've found that you cannot have completely null contents in a
BCB3 TStringGrid Cell.  If you do, the successive (?) /r/n/r/n result
in the following cells in the Row "moving left" one Column.  It's not
really the same issue, but respected posters who have mentioned the
possiblity of (!!) writing to the myAnsiString.c_str() pointer mention
that the Length will then be wrong, unless you also SetLength().

Quote

> > A comparable issue would be how
> > in various versions of BCB it has and has not been possible to
*set*
> > one character in an AnsiString with the [] operator:
myStr[i]='a';

> Which versions were those?  As far as I am aware this has always
been
> possible, as one of the basic uses of the class.  What you haven't
been able
> to do is change a single character in a string *property* this way,

because

I remember reading about this in these newsgroups.  I think BCB1 or 2
allowed you to say myString[i]='a'; , and that you can't do that any
more?  Perhaps the poster's were mistaken, or I misunderstood the
posts.  As I read the Help for the [] operator, it does not hint that
it works in both directions (BCB3).  I really can't research this
properly without the MERS site.  But thank you again.
-------
Timothy H. Buchman
========================================
City Center Theater, New York NY
mailto:tbuchmanREMOVE@NO_SPAMcitycenter.org
Please treat this signature information as confidential.
========================================
Search .borland message archive on http://www.mers.com/searchsite.html

Re:AnsiString , StringList 's AnsiString question


Because the Strings property returns a COPY of the requested string, not the
string instance itself, so when you are trying to write to it directly using
&, you're really writing to the copy, not the real string still contained in
the TStringList.

To do what you want, you have to do it this way:
AnsiString temp = StringList->Strings[0];
test(&temp);
StringList->Strings[0] = temp;

Gambit

"slave of linux" <wm...@ksts.seed.net.tw> wrote in message
news:8rm9jt$7hn1@bornews.borland.com...

Quote
> I am very agreed your opinion,but
> the property Strings of TStringList is Read/Writeable .
> So, why cannot we  use it directly?

Other Threads