M
Michael Brown
I've got some code that looks somewhat like this:
typedef struct TAG_STREAMDATA
{
// Lots of stuff in here ...
double param1, param2;
} STREAMDATA;
class Streamer
{
public:
void GetElement(int id);
int Count(void);
int SetStreamData(STREAMDATA *sd);
};
bool FilterFunc(STREAMDATA &sd) const
{
// Returns true or false depending on the contents of sd.
}
void SomeCalculation(const double p1, const double p2)
{
// Does some stuff
}
void CalculateAll(Streamer &AStreamer, double *p1, double *p2,
STREAMDATA &sd)
{
int NumElements = AStreamer.Count();
for (int id = 0; id < NumElements; id++)
{
AStreamer.GetElement(id);
if (FilterFunc(sd)) SomeCalculation(*p1, *p2);
}
}
void CalculateSpecific(Streamer &AStreamer)
{
STREAMDATA sd;
AStreamer.SetStreamData(&sd);
CalculateAll(AStreamer, &(sd.param1), &(sd.param2), sd);
}
Now, the question is, do I need to declare the sd parameter of CalculateAll
as volatile? The compiler cannot see from the code that sd is changed in the
loop, so my worry is that the call to FilterFunc will be optimised out of
the loop (due to it being a const function). It seems to me that it comes
down to how by-reference parameters are treated by the compiler. If they are
treated as syntactic sugar over pointers, then I think it would operate
correctly (as compilers do not optimise out function calls with pointer
parameters due to the impossibility of figuring out if something has
changed). However, if they are treated as a by-value non-pointer paramter,
then it would fail (the FilterFunc call, being const, could and should be
optimised out of the loop since sd never leaves the function).
Volatile would, as far as I can tell, fix this problem (as would the simpler
solution of just using a pointer instead of by-reference parameters), but I
would still like to know which way by-reference parameters are treated.
Useful references or pointers also accepted
typedef struct TAG_STREAMDATA
{
// Lots of stuff in here ...
double param1, param2;
} STREAMDATA;
class Streamer
{
public:
void GetElement(int id);
int Count(void);
int SetStreamData(STREAMDATA *sd);
};
bool FilterFunc(STREAMDATA &sd) const
{
// Returns true or false depending on the contents of sd.
}
void SomeCalculation(const double p1, const double p2)
{
// Does some stuff
}
void CalculateAll(Streamer &AStreamer, double *p1, double *p2,
STREAMDATA &sd)
{
int NumElements = AStreamer.Count();
for (int id = 0; id < NumElements; id++)
{
AStreamer.GetElement(id);
if (FilterFunc(sd)) SomeCalculation(*p1, *p2);
}
}
void CalculateSpecific(Streamer &AStreamer)
{
STREAMDATA sd;
AStreamer.SetStreamData(&sd);
CalculateAll(AStreamer, &(sd.param1), &(sd.param2), sd);
}
Now, the question is, do I need to declare the sd parameter of CalculateAll
as volatile? The compiler cannot see from the code that sd is changed in the
loop, so my worry is that the call to FilterFunc will be optimised out of
the loop (due to it being a const function). It seems to me that it comes
down to how by-reference parameters are treated by the compiler. If they are
treated as syntactic sugar over pointers, then I think it would operate
correctly (as compilers do not optimise out function calls with pointer
parameters due to the impossibility of figuring out if something has
changed). However, if they are treated as a by-value non-pointer paramter,
then it would fail (the FilterFunc call, being const, could and should be
optimised out of the loop since sd never leaves the function).
Volatile would, as far as I can tell, fix this problem (as would the simpler
solution of just using a pointer instead of by-reference parameters), but I
would still like to know which way by-reference parameters are treated.
Useful references or pointers also accepted