Mega Search
23.2 Million


Sign Up

Make a donation  
Bool in an Object Not Getting Set  
News Group: borland.public.cppbuilder.language.cpp

The following problem has had me running around in circles for the last
three days.

I have an object called TJMCColor.
Here is a small part of it (excerpts):

 public:
  __property int R = {read=GetR,write=SetR};
  __property double H = {read=GetH,write=SetH};
 private:
  int  Red;
  double  Hue;
  void  SetH(double HValue);
  bool RGBSet;
  bool  HSLSet;

----- cpp -----
Code for SetH:
//---------------------------------------------------------------------------
void  TJMCColor::SetH(double HValue)
{
Hue = HValue;
RGBSet = false;
HSLSet = true;
}
//---------------------------------------------------------------------------

The idea is that the object maintains color information in 2 forms, RGB and
HSL.  It is supposed to only perform the transformations when it needs to do
so.  Thus, when H gets set, it sets the bool RGBSet to false so that the
next time one needs to read one of RGB, we will know that the RGB values
need to get computed.
Here's the code for one of those:
//---------------------------------------------------------------------------
int  TJMCColor::GetR()
{
if(!RGBSet)
  {
  ComputeRGB();
  RGBSet = true;
  }
return(Red);
}
//---------------------------------------------------------------------------

Now, here is what happens:
When I go to set H, the code in SetH() executes.  The line setting RGBSet
executes.  But, at the end of the function SetH(), the value of RGBSet is
back to true.
I've opened up a Watch window on it and it looks like it initially gets
changed to false, but then gets changed back to true.  The tooltip evaluator
always shows it as true, even when the Watch window is showing it as false.

Here is the code that calls the set of H:
//---------------------------------------------------------------------------
void __fastcall TSDIAppForm::ResultsGridTopLeftChanged(TObject *Sender)
{
int FirstRow;
TJMCPixel Color;

FirstRow = ResultsGrid->TopRow;
for(int i=FirstRow; i < FirstRow+6; i++)
  {
  if(ResultsGrid->Cells[2][i] != "")
 {
 if(HSLRB->Checked)
      {
   Color.H = StrToFloat(ResultsGrid->Cells[2][i]);         //<---- H is set 
here.
   Color.S = StrToFloat(ResultsGrid->Cells[3][i]);         // The tooltip 
evaluator shows RGBSet as true.
   Color.L = StrToFloat(ResultsGrid->Cells[4][i]);         // It should have 
been set to false.
   }
 else
   {
   Color.R = StrToInt(ResultsGrid->Cells[2][i]);
   Color.G = StrToInt(ResultsGrid->Cells[3][i]);
   Color.B = StrToInt(ResultsGrid->Cells[4][i]);
   }
 DrawColorSample(i+1-FirstRow,&Color);
    }
  }
}
//---------------------------------------------------------------------------
I have tried it with all optimizations turned off, with Codeguard turned
off, and with the object Color in the caller being dynamically allocated
with new instead of automatically.  Nothing made a difference.

System Information:
BDS 2006

Computer:
Gateway with 3GB RAM

Help!
   John



Vote for best question.
Score: 0  # Vote:  0
Date Posted: 5-Jan-2008, at 10:26 AM EST
From: JohnC
 
Re: Bool in an Object Not Getting Set  
News Group: borland.public.cppbuilder.language.cpp
"JD"  wrote in message 
news:477fc3bd$1@newsgroups.borland.com...

> classes must be allocated from the heap, not the stack.

That only applies to Delphi-based classes.  C++ classes that do not derive 
from TObject can be used on the stack or heap.


Gambit 



Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 7-Jan-2008, at 9:44 AM EST
From: Remy Lebeau \(TeamB\)
 
Re: Bool in an Object Not Getting Set  
News Group: borland.public.cppbuilder.language.cpp
"Clayton Arends"  wrote:
>
>> [...] I need Gambit!!
>
> Will I do?

LOL! 

Oh, the imagery! 

Are you better looking?

Can I trust you?



> Only TObject descendants (all VCL classes) need to be
> allocated on the heap.  All other C++ classes can be
> allocated on the stack or the heap.

I've been spending alot of time working with Delphi code and
the lines get fuzzy for me ... Delphi/CG/VCL/C++ . I'm in an
odd spot ... and I'm the local expert! LOL!

As long as the cheque don't bounce!

~ JD


Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 6-Jan-2008, at 7:53 PM EST
From: JD
 
Re: Bool in an Object Not Getting Set  
News Group: borland.public.cppbuilder.language.cpp
"JD"  wrote in message 
news:47804ec0$1@newsgroups.borland.com...

>> Not true. You can allocate classes from the stack, as long
>> as they're not TObject descendents.
>
> That's not how I remember it but I admit that I really only
> focus on VCL which all descends from TObject. I need Gambit!!

Will I do?  Only TObject descendants (all VCL classes) need to be allocated 
on the heap.  All other C++ classes can be allocated on the stack or the 
heap.

Clayton 


Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 6-Jan-2008, at 8:36 AM EST
From: Clayton Arends
 
Re: Bool in an Object Not Getting Set  
News Group: borland.public.cppbuilder.language.cpp
JD wrote:

> Reading an uninitialized variable is Undefined Behavior. As I
> read the OP's code, if it's not initialized, Undefined Behavior
> is the possible culpret.

I must be missing something: I know the OP's code as first shown didn't
initialise member vars, but I didn't see anything in the snippet posted
where it was reading something uninitialised.

> All objects that descend from TObject automatically initialize
> all members to NULL (binary zero).

Thanks, I didn't know that - but I'm glad I don't rely on it! AFAIK
binary zero is not necessarily a valid initialization for all classes,
so could still lead to undefined behaviour in pathological cases...

- Roddy



 


Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 6-Jan-2008, at 8:24 AM EST
From: Roddy Pratt
 
Re: Bool in an Object Not Getting Set  
News Group: borland.public.cppbuilder.language.cpp
"Asger Joergensen"  wrote in message 
news:MPG.21e9ed5ba87774aa9899ca@newsgroups.borland.com...
>
> Hi JD
>
> JD says:
>>
>> and finally, classes
>> must be allocated from the heap, not the stack.
>
> Just curious, but isn't that true only for VCL classes ?
>
> Kind regards
> Asger

Yes, it's true only for VCL classes.

- Arnie 



Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 6-Jan-2008, at 10:03 AM EST
From: Arnie
 
Re: Bool in an Object Not Getting Set  
News Group: borland.public.cppbuilder.language.cpp
>>> and finally, classes must be allocated from the heap, not
>>> the stack. If you want to use the stack, you'll need to
>>> rework your class so that it's a structure instead.
>>
>> Not true. You can allocate classes from the stack, as long
>> as they're not TObject descendents.
>
> That's not how I remember it but I admit that I really only
> focus on VCL which all descends from TObject. I need Gambit!!

There is no c++ requirement that classes be created on the
heap.  This is a VCL/TObject requirement that Remy can
probably explain better than I can.

Also, the only real difference between a structure and a class
is that the structure defaults everything to public where a
class defaults to private.

Initializing member bools in the ctor is a good idea though. 



Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 6-Jan-2008, at 9:33 AM EST
From: Duane Hebert
 
Re: Bool in an Object Not Getting Set  
News Group: borland.public.cppbuilder.language.cpp
"JohnC"  wrote in message 
news:478055b1$1@newsgroups.borland.com...
> I'll try to see if I can reproduce it in a simple application.
> John

OK, I've tried it in a simple application and here's the upside and the 
downside:
The  Application:
void __fastcall TForm1::RunButtonClick(TObject *Sender)
{
TJMCPixel Color;

Color.H = 0.9772;
Color.S = 0.4943;
Color.L = 0.3490;
ProcessColor(&Color);
}
//---------------------------------------------------------------------------
void  TForm1::ProcessColor(TJMCPixel* Color)
{
ShowMessage(Color->R);    //Should show 132
}
//---------------------------------------------------------------------------

The Good Side :-)
   I found the reason that I was not getting the correct answers.  I had 
coded (1/3) in a formula instead of (1.0/3.0).  A dumb beginner's error - a 
fresh look at the code made it obvious.

The Bad Side :-(
   The reason that I was not seeing the flag getting set was apparently 
because the compiler was performing optimization even with all optimizations 
turned off.  As I follow the object through the three assignments to 
Color.H, Color.S and Color.L, the flag shows as true all along even though 
it should be getting repeatedly set to false.  Then, when I get to the call 
ProcessColor(&Color), before I trace into the function, the Color object 
already has the RGB values properly calculated and (of course) the flag is 
set to true.  In other words, the read of the property Color.R has already 
been made - the conversion code has already executed.

Thanks to everyone for their help on this,
   John 



Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 6-Jan-2008, at 6:45 AM EST
From: JohnC
 
Re: Bool in an Object Not Getting Set  
News Group: borland.public.cppbuilder.language.cpp
Dennis:
Thanks for the clear instructions.
Since it was so easy, I decided to try this first.
The only breaks were at the expected points: SetH(),SetS(), and SetL() 
(after the constructor, of course).
So, there was no new information.
I'll now try with a simpler application.
John

"Dennis Jones"  wrote in message 
news:47805c92$1@newsgroups.borland.com...
> To set a data breakpoint, you must be debugging the application first (you 
> cannot set a data breakpoint when the program is not running).  I suggest 
> putting a (normal, source line) breakpoint in the constructor of your 
> class, or some other similar point in the application guaranteed to 
> execute before the problematic code will execute.  Then, when your program 
> breaks at the source breakpoint, go to the "Breakpoint List" window's 
> context menu (right-click), or the "Run" menu item of the main menu, and 
> select "Add Breakpoint | Data Breakpoint."  In the "Address" field, put 
> the name of the variable that you want to monitor ("RGBSet" in your case) 
> and click OK. Then resume execution of your application.
>
> When the value of your "RGBSet" variable changes, the data breakpoint will 
> cause your application to stop immediately at the instruction that caused 
> it to change.  If it is not obvious how or why the responsible code is 
> executing, look at the call stack to see how it got there and that will 
> probably tell you what's happening and why.
>
> Good luck,
>
> - Dennis
>
> 



Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 6-Jan-2008, at 5:41 AM EST
From: JohnC
 
Re: Bool in an Object Not Getting Set  
News Group: borland.public.cppbuilder.language.cpp
"JohnC"  wrote in message 
news:47805748$1@newsgroups.borland.com...
>
> "Dennis Jones"  wrote in message 
> news:477fedd9$1@newsgroups.borland.com...
>> I have had this sort of thing happen to me before too.  Based on my 
>> experience, I think what is probably happening is that another property 
>> setter is (unexpectedly) getting invoked somewhere that you aren't seeing 
>> (sometime after the SetH method exits), causing the values to change 
>> again. Therefore, what I suggest you do is add a data breakpoint, set its 
>> address to that of the RGBSet variable, and then see how/where the value 
>> is changed when the SetH method exits.  That will probably tell you what 
>> is happening and help you figure out how to address the problem.
>
> Thanks, I'll try setting a data breakpoint (as soon as I figure out how to 
> do it).

To set a data breakpoint, you must be debugging the application first (you 
cannot set a data breakpoint when the program is not running).  I suggest 
putting a (normal, source line) breakpoint in the constructor of your class, 
or some other similar point in the application guaranteed to execute before 
the problematic code will execute.  Then, when your program breaks at the 
source breakpoint, go to the "Breakpoint List" window's context menu 
(right-click), or the "Run" menu item of the main menu, and select "Add 
Breakpoint | Data Breakpoint."  In the "Address" field, put the name of the 
variable that you want to monitor ("RGBSet" in your case) and click OK. 
Then resume execution of your application.

When the value of your "RGBSet" variable changes, the data breakpoint will 
cause your application to stop immediately at the instruction that caused it 
to change.  If it is not obvious how or why the responsible code is 
executing, look at the call stack to see how it got there and that will 
probably tell you what's happening and why.

Good luck,

- Dennis



Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 5-Jan-2008, at 8:44 PM EST
From: Dennis Jones