Board index » cppbuilder » Why could the following assertion fail at all?

Why could the following assertion fail at all?


2007-01-30 11:42:49 AM
cppbuilder5
assert(control0!=control1);
int cot=control0->Top;
control1->Top+=control0->Height+vertical_margin;
assert(cot==control0->Top); // <- XXX fails (sometimes)
Why could the *last* assertion fail at all, i.e. why could occur a
side-effect. (Most times it does not fail.)
control0 is a TButton *, control1 a TLabel * (both downcasted to
TControl *). Both are being placed on the same TForm.
And: The form's Height, where both are placed on, has not been
modified by the '+='-assignment.
~~~~~~
I inserted some addtional test/debug-code here, but as before only the
last line fails sometimes.
int cot=control0->Top;
assert(cot==control0->Top);
int tst=control1->Top;
assert(cot==control0->Top);
tst+=control0->Height+vertical_margin;
assert(cot==control0->Top);
control1->Top+=control0->Height+vertical_margin;
assert(cot==control0->Top); // <- fails (sometimes)
~~~~~~
Thanks,
Michael
 
 

Re:Why could the following assertion fail at all?

Quote
And: The form's Height, where both are placed on, has not been
modified by the '+='-assignment.
I think that's where the problem is.
Instead of:
control1->Top+=...
Try:
control1->Top=control1->Top+...
--
Best Regards,
Vladimir Stefanovic
 

Re:Why could the following assertion fail at all?

Quote
I think that's where the problem is.

Instead of:
control1->Top+=...

Try:
control1->Top=control1->Top+...
Sorry, I already tried this (because of experience from AnsiString's
+=), but the result was the same...
Any other idea?
Might there been any technics involved, who avoid the two controls to
overlap, etc.
Thanks,
Michael
 

{smallsort}

Re:Why could the following assertion fail at all?

<MR>wrote in message
Quote
control1->Top+=control0->Height+vertical_margin;
You can't use the '+=' operator with properties. You hve to use the
'=' and '+' operators separately, ie:
control1->Top = control1->Top + control0->Height +
vertical_margin;
Quote
assert(cot==control0->Top); // <- XXX fails (sometimes)

Why could the *last* assertion fail at all
The only way it could fail is if moving control1 is also moving
control0 as well, such as if they are aligned to each either (directly
or indirectly).
Gambit
 

Re:Why could the following assertion fail at all?

"Remy Lebeau \(TeamB\)" < XXXX@XXXXX.COM >schrieb:
Quote

<MR>wrote in message
news: XXXX@XXXXX.COM ...

>control1->Top+=control0->Height+vertical_margin;

You can't use the '+=' operator with properties. You hve to use the
'=' and '+' operators separately, ie:

control1->Top = control1->Top + control0->Height +
vertical_margin;
Ok, I changed it in my source-code. As said this does not change
anything on the situation itself. The (last) assertion did fail.
[A little off-topic: May I ask what's the reason the +=-operator
should/can not be used with properties? Is there a reason it exists
for them at all. (Ok, this is probably because += is defined for e.g.
int, so it is automatically defined for a property of type int. But if
this is the rason, why not explicitely implement it for the properties
or return a compiler-error? The compiler should b e able to check if a
left-assignement operator is a property or not, shouldn't it?]
[Before the critical assignment, the controls hold the following
values:
control0->Top=268. control1->Top=
Afterwards
control0->Top=280, control1->Top=
(B.t.w.: control0->Height==25, control1->Height==13, i.e. these
heights seem not to be added to the Top-value of control0->Top)]
Quote

>assert(cot==control0->Top); // <- XXX fails (sometimes)
>
>Why could the *last* assertion fail at all

The only way it could fail is if moving control1 is also moving
control0 as well, such as if they are aligned to each either (directly
or indirectly).
Probably this is the point. But how could this be? They are just being
placed in the form, as far as I know one independent from each other.
Are there any properties I can ckeck for them being related/aligned in
any way?
I tried to dive into the VCL, but unfortunately I only got assembler
code. Is there a way to debug it on source-code-level? I found no
appropriate option in the options-menu.
I even tried to get down into assembler. But unfortunately the
de{*word*81} did not evaluate expressions like
((TControl *)0xb54f70)->Top
when I'm inside an 'assembler-function' without source-code.
Thanks,
Michael
 

Re:Why could the following assertion fail at all?

<MR>wrote in message
Quote
Ok, I changed it in my source-code. As said this does not change
anything on the situation itself. The (last) assertion did fail.
I did not say that it would change anything.
Quote
May I ask what's the reason the +=-operator should/can not be
used with properties?
Because it is not implemented for properties to begin with.
Quote
Is there a reason it exists for them at all.
It doesn't exist for properties. That's the problem.
Quote
Ok, this is probably because += is defined for e.g. int, so it is
automatically defined for a property of type int.
No, it is not defined for the property. It is called on the value
that the property returns, which is not the same thing. In other
words, when you call the following:
control1->Top += ...;
It is like calling this instead:
int temp = control1->GetTop();
temp += ...;
Quote
But if this is the rason, why not explicitely implement it for the
properties
Because Borland hasn't implementd it for propeties yet.
Quote
or return a compiler-error?
Because it is not a compiler error.
Quote
The compiler should b e able to check if a left-assignement operator
is
a property or not, shouldn't it?
Not currently, no.
Quote
>The only way it could fail is if moving control1 is also moving
>control0 as well, such as if they are aligned to each either
(directly
>or indirectly).

Probably this is the point. But how could this be?
Since you have not provided any details about your UI or your real
code, there is no way to answer that.
Quote
I tried to dive into the VCL, but unfortunately I only got assembler
code. Is there a way to debug it on source-code-level?
If you have the VCL source installed, then enable the "Use debug
libraries" item in the Project Options, and also include
"$(BCB)\Source\VCL" in the Debug path.
Gambit
 

Re:Why could the following assertion fail at all?

Quote
>Ok, this is probably because += is defined for e.g. int, so it is
>automatically defined for a property of type int.

No, it is not defined for the property. It is called on the value
that the property returns, which is not the same thing. In other
words, when you call the following:

control1->Top += ...;

It is like calling this instead:

int temp = control1->GetTop();
temp += ...;

Than Borland must have changed something. In the BDS2006-version doing
this '+='-operator for the 'Top' definitely changes the property's
value. In fact, the function my code is placed in works exactly the
same way with '+=' as with '+'. But, if this is not 100% sure (and not
for all former versions I'll replace it by '+').
Quote
>I tried to dive into the VCL, but unfortunately I only got assembler
>code. Is there a way to debug it on source-code-level?

If you have the VCL source installed, then enable the "Use debug
libraries" item in the Project Options, and also include
"$(BCB)\Source\VCL" in the Debug path.
Now I checked it several times, but I could not find such an option in
BDS2006 Professional. Switching over to BCB6 Personal, I found it in
the Project-Options - Linker, but with BDS2006 I could not find this
option anywhere, although the vcl-source exists in
$(BDS)/source/win32/vcl. I included the source-directory anyway and
recompiled, but could not get in.
Quote
I even tried to get down into assembler. But unfortunately the
de{*word*81} did not evaluate expressions like
((TControl *)0xb54f70)->Top
when I'm inside an 'assembler-function' without source-code.
Is there a way to access to
control1->Top
anyway inside the cpu-code?
I tried
((TControl *)0xb54f70)->Top,
where 0xb54f70 is the actual address of control1 and the result is
displayed correctly from inside my source-code, but diving into the
assembler-area it was not displayed anymore.
It would help to find out, which function changes the Top-value of my
control.
Thanks,
Michael
The source code
 

Re:Why could the following assertion fail at all?

ALL SOLVED!
Quote
>>I tried to dive into the VCL, but unfortunately I only got assembler
>>code. Is there a way to debug it on source-code-level?
>
>If you have the VCL source installed, then enable the "Use debug
>libraries" item in the Project Options, and also include
>"$(BCB)\Source\VCL" in the Debug path.
Now I checked it several times, but I could not find such an option in
BDS2006 Professional. Switching over to BCB6 Personal, I found it in
the Project-Options - Linker, but with BDS2006 I could not find this
option anywhere, although the vcl-source exists in
$(BDS)/source/win32/vcl. I included the source-directory anyway and
recompiled, but could not get in.
For this I found the solution in group borland.cppbuilder.ide from an
answer to another posting from David Dean:
To trace into the VCL-Source in Debug-Mode, one has to
(1) In
Projekt-Optionen...-Packages
[Project-Options...-Packages]
one has to turn off
Laufzeit-Packages: [-] Laufzeit-Packages verwenden
[Runtime-Packages: [-] Use Runtime-Packages]
AND
(2) In
Projekt-Optionen...-Linker (ilink32)-Linken
Project-Options...-Linker (ilink32)-Linking]
one has to turn off
Linken: [-] Dynamische RTL verwenden
Linking: [-] Use dynamic RTL)
To not trace into VCL-Source disable one of these options
Quote
>I even tried to get down into assembler. But unfortunately the
>de{*word*81} did not evaluate expressions like
>((TControl *)0xb54f70)->Top
>when I'm inside an 'assembler-function' without source-code.
Is there a way to access to
control1->Top
anyway inside the cpu-code?
I tried
((TControl *)0xb54f70)->Top,
where 0xb54f70 is the actual address of control1 and the result is
displayed correctly from inside my source-code, but diving into the
assembler-area it was not displayed anymore.
It would help to find out, which function changes the Top-value of my
control.
When inside VCL-Source (instead of the CPU-window), expressions like
((TControl *)0xb54f70)->Top,
work fine and display the correct result.
~~~~~~~~~~~~~~
And finally I found out, that the assignment of contro0->Top to the
undesired value came from the call of
SetTop()
SetBounds()
...
RequestAlign
Parent.AlignControl(Self); <- undesired assignment done here
This last delphi-function changed control2->Top, which has the same
form form as parent as control1.
This is a little strange, because neither form->Left/Top/Width/Height
did change (i proved this).
Nevertheless, temporarily disabling these kind of alignment-correction
(TWinControl::DisableAlign()) (and enabling it afterwards) solved my
problem.
Thanks,
Michael
 

Re:Why could the following assertion fail at all?

<MR>wrote in message
Quote
RequestAlign
Parent.AlignControl(Self); <- undesired assignment done here

This last delphi-function changed control2->Top, which has
the same form form as parent as control1.
Which is exactly what I suspected, and hinted at earlier. Your
controls are aligned relative to each other. Change one and the other
can change as well.
Quote
This is a little strange, because neither
form->Left/Top/Width/Height
did change (i proved this).
It is not supposed to. You are not changing the form itself.
Gambit
 

Re:Why could the following assertion fail at all?

Quote

>RequestAlign
>Parent.AlignControl(Self); <- undesired assignment done here
>
>This last delphi-function changed control2->Top, which has
>the same form form as parent as control1.

Which is exactly what I suspected, and hinted at earlier. Your
controls are aligned relative to each other. Change one and the other
can change as well.
Yes, you did. But I still have no idea how such an alignment between
two controls on a common form could look like. It should be visible
somehow in the Object-Inspector's properties of these controls,
shouldn,t it?
Michael
 

Re:Why could the following assertion fail at all?

<MR>wrote in message
Quote
Yes, you did. But I still have no idea how such an alignment
between two controls on a common form could look like.
That is controlled by the Align property.
Gambit
 

Re:Why could the following assertion fail at all?

Quote
That is controlled by the Align property.
But Align does only concern the alignment to the parent-component (in
this case the form both controls are placed in) and not an alignment
between two controls inside the same form. At least the documentation
says so...
Michael
 

Re:Why could the following assertion fail at all?

<MR>wrote:
Quote

>That is controlled by the Align property.

But Align does only concern the alignment to the parent-
component (in this case the form both controls are placed
in) and not an alignment between two controls inside the
same form.
What the means is that the controls are aligned in reference
to the Parent control - not in reference to sibling controls.
However, one control can affect the alignment of a sibling.
For example, drop 2 TPanels on an empty form and change their
Align property. Set one to alRight and then look what happens
when you set the other to alTop.
Note that the alRight Panel's Top (and Height) is no longer
the same. So, changing one sibling's properties *can* change
the other and looking at the code that you posted, you are
indeed doing that.
Why it doesn't always fail or always pass is a mystery to me
and the only reason that I can think of for this is that the
variance between the 2 controls is not constant.
~ JD