Modifying through pointer-to-const

D

Dave

Hello all,

In the code below, I am able to modify data through the pointer-to-const
DynGapRec parameter. The last two lines show this. I didn't want to create
a huge message, so there's a *lot* of context that's missing. If this is
not enough to work with, I will, of course, understand. My question is: Is
there *any* circumstance where this should be legal, or do I definitely have
a compiler bug (VC++ 7.1)?

Thanks,
Dave

void CInstrProcEngine::AggregateDynamicGapRecords(const CAccount* iAcct,
const SingleInstr* pInstr,
const int* evPoints,
const CGapInt* pGap,
const DynGap* DynGapRec,
CDate forecastDate,
int RateType,
int startPd,
int endPd)
{
if (pGap->i_NumGapIntervals <= 0)
return;

int index = 0;
int NumEvPts = 0;
int currentEvPt = 0;
double nMoROBal;

double* SaleAmt = pInstr->SaleAmt;
double SaleAdjustment[MAX_PERIOD + 2] = {0.0};

while (currentEvPt < LAST_PERIOD && (index < DynGapRec->mTotPds))
{
if (evPoints[currentEvPt])
{
BOOL reprFlag = FALSE;

NumEvPts++;

CDate tempDate;
tempDate = forecastDate;
tempDate.AddMonths(currentEvPt);

SaleAmt = pInstr->SaleAmt;
if(!pInstr->SrvcFlag)
{
double notUsed = 0;

CalcSalesAdjustment(
currentEvPt,
endPd + 1,
pInstr->UnModContractualRo,
pInstr->OvPrepayments,
pInstr->EvInterestCashflow,
pInstr->SaleAmt,
forecastDate,
SaleAdjustment,
notUsed,
false
);

SaleAmt = SaleAdjustment;
}

// calculate gap buckets
for (int gapRecCnt=0; gapRecCnt < pGap->i_NumGapIntervals;
gapRecCnt++)
{
DynGaRec->MvPeriod[index] = currentEvPt; // ILLEGAL!!!
DynGapRec->GapInteval[index] = pGap->i_GapEndMt[gapRecCnt]; //
ILLEGAL!!!

.. . .
.. . .
.. . .
.. . .
}
 
W

Walter Tross

(snip)
DynGaRec->MvPeriod[index] = currentEvPt; // ILLEGAL!!!
DynGapRec->GapInteval[index] = pGap->i_GapEndMt[gapRecCnt]; //
ILLEGAL!!!

It looks like MyPeriod and GapInterval are pointers, not arrays. In
this case they are const (because of your passing a const DynGap*
DynGapRec), but what they point to is not.
 
R

Russell Hanneken

Dave said:
In the code below, I am able to modify data through the pointer-to-const
DynGapRec parameter. The last two lines show this.
Is there any circumstance where this should be legal, or
do I definitely have a compiler bug (VC++ 7.1)?

void CInstrProcEngine::AggregateDynamicGapRecords(const CAccount*
iAcct, const SingleInstr* pInstr,
const int* evPoints,
const CGapInt* pGap,
const DynGap* DynGapRec,
CDate forecastDate,
int RateType,
int startPd,
int endPd)
{ [. . .]
DynGaRec->MvPeriod[index] = currentEvPt; // ILLEGAL!!!
DynGapRec->GapInteval[index] = pGap->i_GapEndMt[gapRecCnt]; //
ILLEGAL!!!

Dave,

This would be legal if MvPeriod and GapInteval are pointers to non-const
data. Assuming this is the case, you're changing the values of data being
pointed to, not the values of the pointers per se. Since the pointers are
members of DynGap, and the data being pointed to are not, the assignments
don't affect the state of DynGapRec (as far as the compiler is concerned,
anyway).

If this is not what you want, you might consider hiding MvPeriod and
GapInterval, and providing non-const member functions to alter the data they
point to.
 
D

Dan Bloomquist

Russell said:
Dave said:
In the code below, I am able to modify data through the pointer-to-const
DynGapRec parameter. The last two lines show this.
Is there any circumstance where this should be legal, or
do I definitely have a compiler bug (VC++ 7.1)?

void CInstrProcEngine::AggregateDynamicGapRecords(const CAccount*
iAcct, const SingleInstr* pInstr,
const int* evPoints,
const CGapInt* pGap,
const DynGap* DynGapRec,
CDate forecastDate,
int RateType,
int startPd,
int endPd)
{

[. . .]
DynGaRec->MvPeriod[index] = currentEvPt; // ILLEGAL!!!
DynGapRec->GapInteval[index] = pGap->i_GapEndMt[gapRecCnt]; //
ILLEGAL!!!


Dave,

This would be legal if MvPeriod and GapInteval are pointers to non-const
data. Assuming this is the case, you're changing the values of data being
pointed to, not the values of the pointers per se. Since the pointers are
members of DynGap, and the data being pointed to are not, the assignments
don't affect the state of DynGapRec (as far as the compiler is concerned,
anyway).

I've tested in 7.1 and this is the case. If the member is declared
const, then the compiler will balk.

Best, Dan.
 
W

Walter Tross

I've tested in 7.1 and this is the case. If the member is declared
const, then the compiler will balk.

Don't confuse a const pointer member with a member which is a pointer
to const, i.e., T* const p (a const pointer) with const T* p (a
pointer to const). Anyhow, if T* m is a member of a class C which is
passed by a const C* c, c->m is treated as being of type T* const, not
of type const T*
 
D

Dan Bloomquist

Walter said:
Don't confuse a const pointer member with a member which is a pointer
to const, i.e., T* const p (a const pointer) with const T* p (a
pointer to const). Anyhow, if T* m is a member of a class C which is
passed by a const C* c, c->m is treated as being of type T* const, not
of type const T*

Hi Walter,
Thank you.

I tested first as the op posted:
DynGaRec->MvPeriod[index] = currentEvPt; // ILLEGAL!!!

So he was not modifying the pointer.

As you say:
struct TS {
int* test;
};

void test( const TS* test )
{
test->test= NULL; //const error.
*test->test= 2; //ok.
}

also:
struct TS {
const int* mtest;
};

void test( TS* test )
{
*test->mtest= 2; //const error.
test->mtest= NULL; //ok.
}

and if:
struct TS {
int* const test;
};
void test( TS* test )
{
*test->mtest= 2; //ok.
test->mtest= NULL; //const error.
}

It appears 7.1 is working properly.

Best, Dan.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,166
Messages
2,570,902
Members
47,442
Latest member
KevinLocki

Latest Threads

Top