On const and the lack thereof

D

Daniel

It's been about 11 years since I've programmed in this language.
Anyway, using Visual Studio 2005 ...

I'm using a third party library that requires me to implement the
virtual operator

class CostFunctor
{
double operator()(const std::vector<double>& v) const {
...
}

double* x;
int dimx;
MyData* data;
}

Within this operator, I need to change the implementation to delegate
to a C function,

void costFunction(double *v, int dimv, double *x, int dimx, void
*data);

costFunction doesn't change v, does change x, and also changes data
(after casting back to MyData*.).

v I pass as const_cast<double*>(&v[0]).

I tried declaring x and data with mutable. That worked for data. But
when I tried declaring x as

mutable double* x;

it compiled, but resulted in a runtime "write to protected memory"
error inside costFunction. I then tried

double* mutable x;

which worked, but why that and not the other?

Any comments on the safest way of implementing this interface would be
appreciated (it's not possible to modify the interface of CostFunctor
or the signature of costFunction.)

Thanks,
Daniel
 
A

Alf P. Steinbach /Usenet

* Daniel, on 06.07.2010 23:53:
It's been about 11 years since I've programmed in this language.
Anyway, using Visual Studio 2005 ...

I'm using a third party library that requires me to implement the
virtual operator

class CostFunctor
{
double operator()(const std::vector<double>& v) const {
...
}

double* x;
int dimx;
MyData* data;
}

Within this operator, I need to change the implementation to delegate
to a C function,

void costFunction(double *v, int dimv, double *x, int dimx, void
*data);

costFunction doesn't change v, does change x, and also changes data
(after casting back to MyData*.).

v I pass as const_cast<double*>(&v[0]).

I tried declaring x and data with mutable. That worked for data. But
when I tried declaring x as

mutable double* x;

it compiled, but resulted in a runtime "write to protected memory"
error inside costFunction. I then tried

double* mutable x;

which worked, but why that and not the other?

Probably it had nothing whatsoever to do with 'mutable' or not, but rather with
using an uninitialized pointer (namely 'x').

You don't need 'mutable'.

Any comments on the safest way of implementing this interface would be
appreciated (it's not possible to modify the interface of CostFunctor
or the signature of costFunction.)

Are you sure that the third party library requires the presence of the members
x, dimx and data, and not just the operator()?

It's a bit unclear what the required interface really is.


Cheers & hth.,

- Alf
 
D

Daniel

* Daniel, on 06.07.2010 23:53:
Probably it had nothing whatsoever to do with 'mutable' or not, but rather with
using an uninitialized pointer (namely 'x').

No, x is allocated and initialized.
You don't need 'mutable'.


It's a bit unclear what the required interface really is.

The only thing relevent about the interface is the signature of
operator(), but more concretely ...

class ICostFunctor
{
public:
virtual double operator()(const std::vector<double>& v) const =
0;
};

So

class CostFunctor : public ICostFunctor
{
public:
// Constructor, destructor

inline
double operator()(const std::vector<double>& v) const
{
costFunction(const_cast<double*>&v[0],
v.size(),
x,
dimx,
data);
...
}

double mutable* x;
int dimx;
mutable MyData* data;
};

runs and does what it's supposed to do, but substituting

mutable double* x;

compiles but results in a run-time "writing to protected memory" error
(with Visual Studio 2005). Expected? Unexpected?

Thanks,
Daniel
 
I

Ian Collins

No, x is allocated and initialized.

Then you should show this code.
You don't need 'mutable'.


It's a bit unclear what the required interface really is.

The only thing relevent about the interface is the signature of
operator(), but more concretely ...

class ICostFunctor
{
public:
virtual double operator()(const std::vector<double>& v) const =
0;
};

So

class CostFunctor : public ICostFunctor
{
public:
// Constructor, destructor

inline
double operator()(const std::vector<double>& v) const
{
costFunction(const_cast<double*>&v[0],
v.size(),
x,
dimx,
data);

What is the signature of costFunction?
 
D

Daniel

Then you should show this code.
Irrelevent detail - assume it's initialized (it is.)
The only thing relevent about the interface is the signature of
operator(), but more concretely ...
class ICostFunctor
{
public:
      virtual double operator()(const std::vector<double>&   v) const =
0;
};

class CostFunctor : public ICostFunctor
{
public:
      //  Constructor, destructor
      inline
      double operator()(const std::vector<double>&   v) const
      {
         costFunction(const_cast<double*>&v[0],
                      v.size(),
                      x,
                      dimx,
                      data);

What is the signature of costFunction?
Repeated from my original post:

void costFunction(double *v, int dimv, double *x, int dimx, void
*data);

-- Daniel
 
Ö

Öö Tiib

* Daniel, on 06.07.2010 23:53:
Probably it had nothing whatsoever to do with 'mutable' or not, but rather with
using an uninitialized pointer (namely 'x').

No, x is allocated and initialized.


You don't need 'mutable'.
It's a bit unclear what the required interface really is.

The only thing relevent about the interface is the signature of
operator(), but more concretely ...

class ICostFunctor
{
public:
     virtual double operator()(const std::vector<double>&  v) const =
0;

};

So

class CostFunctor : public ICostFunctor
{
public:
     //  Constructor, destructor

     inline
     double operator()(const std::vector<double>&  v) const
     {
        costFunction(const_cast<double*>&v[0],
                     v.size(),
                     x,
                     dimx,
                     data);
        ...
     }

     double mutable* x;
     int dimx;
     mutable MyData* data;

};

runs and does what it's supposed to do, but substituting

mutable double* x;

compiles but results in a run-time "writing to protected memory" error
(with Visual Studio 2005).  Expected?  Unexpected?

Can not you run it in debugger and check what is wrong and awriting to
what it crashes? It sounds like some usual trivial problem. For
example i think you may not do &v[0] when v.empty() is true but your
code does not seemingly detect it.
 
D

Daniel

Can not you run it in debugger and check what is wrong and awriting to
what it crashes? It sounds like some usual trivial problem. For
example i think you may not do &v[0] when v.empty() is true but your
code does not seemingly detect it.
Hi Öö,

Thanks for responding. But my questions aren't about the conditions
under which it works, and which it doesn't, I know that (and besides,
I rarely if ever use debuggers.) I don't need help getting something
to work, I already have it working. Maybe I'm not being clear enough,
let me rephrase my questions.

I'm using a third party library that requires providing an
implementation of the following interface.

class ICostFunctor
{
public:
virtual double operator()(const std::vector<double>& v) const =
0;

};

Note that operator() is const, while my implementation will require
passing state as arguments to a C function that will modify that
state. Note also that v is passed as a const reference to
vector<double>, but the C function is expecting it as a non-const
array of double, although it does not modify it.

The signature of the C function is

void costFunction(double *v, int dimv, double *x, int dimx,
void *data);

costFunction doesn't modify v, does modify x, and also modifies data
(after casting back to MyData*.).

So, my working implementation looks like

class CostFunctor : public ICostFunctor
{
public:
// Constructor, destructor

inline
double operator()(const std::vector<double>& v) const
{
costFunction(const_cast<double*>&v[0],
v.size(),
x,
dimx,
data);
...
}

double mutable* x;
int dimx;
mutable MyData* data;

};

This works, my costFunction involves solving a 4 parameter PDE
equation on a 3-dim mesh, and it's happily running as I type.

But, if I change the declaration of the x data member to

mutable double* x;

I get a fault, "trying to write to protected memory", using Visual
Studio 2005. Consistently, and with no other changes. And to
specifically answer your question, it happens when costFunction
attempts to write to x, as you would expect if x were indeed protected
memory.

So, my questions are:

1. What is the difference, if any, between "double mutable*" and
"mutable double*"? Is there any language reason why costFunction
would see the first as protected memory and the second as unprotected
memory, given that operator() is const? Is this a language issue or a
compiler implementation issue?

2. What are the implications of operator() being const? I understand
that the "this" pointer inside the function becomes const, but there
seems also to be a suggestion that a call to the operator() not mutate
the state of the object, but at the same time nothing stops me from
changing the entries in data member x as long as I'm within the body
of operator(), even if x is not declared mutable. But once I pass x
as an argument to a C function, I'm seeing the "protected memory"
issue, if I haven't declared x as "double mutable*", in Visual Studio
2005. Is this expected? Unexpected?

3. Integrating C++ callback interfaces, that have const member
functions and that take const references, with C functions, that take
non-const pointer arguments for both input and output, is a fairly
common problem. I would be interested in suggestions for general good
practice guidelines, in the context of the problem I posed above.

Thanks,
Daniel
 
I

Ian Collins

But, if I change the declaration of the x data member to

mutable double* x;

As Alf said earlier, you don't need 'mutable'. You are not changing the
value of x or data in your const member.
I get a fault, "trying to write to protected memory", using Visual
Studio 2005. Consistently, and with no other changes. And to
specifically answer your question, it happens when costFunction
attempts to write to x, as you would expect if x were indeed protected
memory.

So what is x initialised to? You said this was irrelevant, but it
appears it is relevant. Not checking why with a debugger is silly.
So, my questions are:

1. What is the difference, if any, between "double mutable*" and
"mutable double*"? Is there any language reason why costFunction
would see the first as protected memory and the second as unprotected
memory, given that operator() is const? Is this a language issue or a
compiler implementation issue?

It sounds like the latter. "mutable double*" is declaring the pointer
as mutable. "double mutable*" would be declaring the data pointed to as
mutable, which strikes me as odd because it already is!
2. What are the implications of operator() being const? I understand
that the "this" pointer inside the function becomes const, but there
seems also to be a suggestion that a call to the operator() not mutate
the state of the object, but at the same time nothing stops me from
changing the entries in data member x as long as I'm within the body
of operator(), even if x is not declared mutable. But once I pass x
as an argument to a C function, I'm seeing the "protected memory"
issue, if I haven't declared x as "double mutable*", in Visual Studio
2005. Is this expected? Unexpected?

In this case, you aren't changing the values of the pointers, so there
aren't any implications and mutable is not required.
3. Integrating C++ callback interfaces, that have const member
functions and that take const references, with C functions, that take
non-const pointer arguments for both input and output, is a fairly
common problem. I would be interested in suggestions for general good
practice guidelines, in the context of the problem I posed above.

It is, but I think you have mixed up the concepts of a const pointer and
a pointer to const data.
 
D

Daniel

It sounds like the latter.  "mutable double*" is declaring the pointer
as mutable. "double mutable*" would be declaring the data pointed to as
mutable, which strikes me as odd because it already is!


In this case, you aren't changing the values of the pointers, so there
aren't any implications and mutable is not required.


It is, but I think you have mixed up the concepts of a const pointer and
a pointer to const data.
You were doing great until you got to here :)

But thanks, I'll conclude that it is a compiler implementation issue,
and stick with my work around.

Best regards,
Daniel
 
Ö

Öö Tiib

Can not you run it in debugger and check what is wrong and awriting to
what it crashes? It sounds like some usual trivial problem. For
example i think you may not do &v[0] when v.empty() is true but your
code does not seemingly detect it.

Hi Öö,

Thanks for responding.  But my questions aren't about the conditions
under which it works, and which it doesn't, I know that (and besides,
I rarely if ever use debuggers.)  I don't need help getting something
to work, I already have it working.  Maybe I'm not being clear enough,
let me rephrase my questions.

I'm using a third party library that requires providing an
implementation of the following interface.

class ICostFunctor
{
public:
     virtual double operator()(const std::vector<double>&  v) const =
0;

};

Note that operator() is const, while my implementation will require
passing state as arguments to a C function that will modify that
state.  Note also that v is passed as a const reference to
vector<double>, but the C function is expecting it as a non-const
array of double, although it does not modify it.

The signature of the C function is

void costFunction(double *v, int dimv, double *x, int dimx,
void *data);

costFunction doesn't modify v, does modify x, and also modifies data
(after casting back to MyData*.).

So, my working implementation looks like

class CostFunctor : public ICostFunctor
{
public:
     //  Constructor, destructor

     inline
     double operator()(const std::vector<double>&  v) const
     {
        costFunction(const_cast<double*>&v[0],
                     v.size(),
                     x,
                     dimx,
                     data);
        ...
     }

     double mutable* x;
     int dimx;
     mutable MyData* data;

};

This works, my costFunction involves solving a 4 parameter PDE
equation on a 3-dim mesh, and it's happily running as I type.

But, if I change the declaration of the x data member to

mutable double* x;

I get a fault, "trying to write to protected memory", using Visual
Studio 2005.  Consistently, and with no other changes.  And to
specifically answer your question, it happens when costFunction
attempts to write to x, as you would expect if x were indeed protected
memory.

That is some sort of .NET error. No such thing in C++.
So, my questions are:

1.  What is the difference, if any, between "double mutable*" and
"mutable double*"?  Is there any language reason why costFunction
would see the first as protected memory and the second as unprotected
memory, given that operator() is const?  Is this a language issue or a
compiler implementation issue?

"double mutable*" is perhaps same as "mutable double*" by standard,
only that it looks unusual. It should work the same and that mutable
keyword should not be even needed there at all for your code to work
the same.
2. What are the implications of operator() being const?  I understand
that the "this" pointer inside the function becomes const, but there
seems also to be a suggestion that a call to the operator() not mutate
the state of the object, but at the same time nothing stops me from
changing the entries in data member x as long as I'm within the body
of operator(), even if x is not declared mutable.  But once I pass x
as an argument to a C function, I'm seeing the "protected memory"
issue, if I haven't declared x as "double mutable*", in Visual Studio
2005.  Is this expected?  Unexpected?

C++/CLI is not really C++. It is MS extension to C++. Access and const-
correctness in real C++ is considered compile-time only. Perhaps
whatever of that mutable and C++/CLI checking access to memory
that .NET considers protected is somehow confused by it. The wonders
of C++/CLI are perhaps best explained by gurus in some group that
discusses C++/CLI.

What i can suggest is to turn to "No Common Language Runtime support"
in your VS 2005 project options. Then it is most likely that you can
find help in this group. Also it is most likely that particular
problem will go away just like that.
3. Integrating C++ callback interfaces, that have const member
functions and that take const references, with C functions, that take
non-const pointer arguments for both input and output, is a fairly
common problem.  I would be interested in suggestions for general good
practice guidelines, in the context of the problem I posed above.

Good practice i think is to remove mutable where no mutable is needed.
The "const" keyword is present in C too and behaves similarly, so i am
not sure that it is really that common problem. People tend to keep
const correctness in both languages.
 
D

Daniel

C++/CLI is not really C++. It is MS extension to C++. Access and const-
correctness in real C++ is considered compile-time only. Perhaps
whatever of that mutable and C++/CLI checking access to memory
that .NET considers protected is somehow confused by it.

Possibly, these classes are not written as managed code, so I didn't
think of that, but they do belong to an assembly that has a .net
interface to the outside world. It might be judicious to collect the
unmanaged code in a static library. Good point, thanks.
Good practice i think is to remove mutable where no mutable is needed.
The "const" keyword is present in C too and behaves similarly, so i am
not sure that it is really that common problem. People tend to keep
const correctness in both languages.
The problem posed, though, rules that out as an option, you don't have
the option of changing signatures, the signatures are contracts
specified by third party libraries.

Best regards,
Daniel
 
R

Richard

[Please do not mail me a copy of your followup]

You can accomplish this with simple delegation.

class Coster
{
public:
double operator()(std::vector<double> const &v)
{
double result = 0.0;
// do whatever you want here, with whatever state you want
return result;
}
};

class CostFunctorImpl : public ICostFunctor
{
public:
virtual double operator()(std::vector<double> const &v) const
{
Coster c;
return c(v);
}
};

CostFunctorImpl::eek:perator() doesn't modify any state in CostFunctorImpl.
Coster does all the work doing whatever it wants with whatever state
it has.

IMO, this is much cleaner than decorating everything with const_cast<>
or mutable. If Coster's implementation is inline, the compiler should
be able to do a decent job of getting rid of any overhead introduced
by delegating to another class.
 
J

James Kanze

I'm using a third party library that requires providing an
implementation of the following interface.
class ICostFunctor
{
public:
virtual double operator()(const std::vector<double>& v) const = 0;
};
Note that operator() is const, while my implementation will
require passing state as arguments to a C function that will
modify that state. Note also that v is passed as a const
reference to vector<double>, but the C function is expecting
it as a non-const array of double, although it does not modify
it.

An interesting question is why the base class declares this
function const? Is it making copies of it, so that it would
make no sense to modify any derived class members? Or is it
just to allow temporary instances to be passed to the callback.
The signature of the C function is
void costFunction(double *v, int dimv, double *x, int dimx,
void *data);
costFunction doesn't modify v, does modify x, and also
modifies data (after casting back to MyData*.).
So, my working implementation looks like
class CostFunctor : public ICostFunctor
{
public:
// Constructor, destructor

inline
double operator()(const std::vector<double>& v) const
{
costFunction(const_cast<double*>&v[0],
v.size(),
x,
dimx,
data);
...
}

double mutable* x;
int dimx;
mutable MyData* data;
};
This works, my costFunction involves solving a 4 parameter PDE
equation on a 3-dim mesh, and it's happily running as I type.
But, if I change the declaration of the x data member to
mutable double* x;
I get a fault, "trying to write to protected memory", using
Visual Studio 2005.

That is strange, because the two statements are perfectly
identical. (Order is irrelevant in a decl-specifier-seq, and
even things like "long mutable int" are legal.) I knocked up an
extremely simplified version of your code, and I found no
difference in the generated code, regardless of whether I wrote
"double*", "mutable double*", or "double mutable*".
Consistently, and with no other changes. And to specifically
answer your question, it happens when costFunction attempts to
write to x, as you would expect if x were indeed protected
memory.

From the language/compiler point of view, the const on the
object only applies to the declared members themselves, not what
they point to. For what you've described, you shouldn't need
mutable at all. The mutable's you've provided allow modifying
the pointers in a const function (which you don't do). Whether
the CostFunctor objecdt is const or not, you have the right to
modify what the pointers point to, since you haven't declared
them const. (From the language/compiler point of view.
Normally, if the pointed to data is logically part of the
CostFunctor state, then you shouldn't modify it in a const
functions. Your case may be an exception, however, if the const
in ICostFunctor is only to allow temporaries.)
So, my questions are:
1. What is the difference, if any, between "double mutable*" and
"mutable double*"?

Absolutely none.
Is there any language reason why costFunction would see the
first as protected memory and the second as unprotected
memory, given that operator() is const? Is this a language
issue or a compiler implementation issue?

Probably neither. It's certainly not a language issue, and
I suspect that it's not a compiler implementation issue, but
something related to the way you're testing the code.
2. What are the implications of operator() being const?

That the type of "this" is CostFunctor const*, rather than just
CostFunctor*, and that the function can't be called through an
lvalue expression whose type is not const.
I understand that the "this" pointer inside the function
becomes const, but there seems also to be a suggestion that
a call to the operator() not mutate the state of the object,

The suggestion that nothing mutate the state of the object is
*not* a language issue, but simply a convention. The language
doesn't no anything about the state of the object, as such.

There is (or was once---I'm not sure if it survived
standardization) a rule which says that if the actual object is
const, and you attempt to modify it, the code has undefined
behavior (unless the object has user defined
constructors?---that was the original rule). I'm not sure what
the rule is concerning the modification of a temporary object.
But none of that is really relevant here, because as far as the
language is concerned, only the pointers are part of the object,
and not what they point to.
but at the same time nothing stops me from changing the
entries in data member x as long as I'm within the body of
operator(), even if x is not declared mutable. But once
I pass x as an argument to a C function, I'm seeing the
"protected memory" issue, if I haven't declared x as "double
mutable*", in Visual Studio 2005. Is this expected?
Unexpected?

I'd need a complete, compilable example to say more. There's
nothing in what you've posted to explain the behavior you're
describing, and I'm very, very sceptical that it is due to
a compiler error.
 
J

James Kanze

[...]
It sounds like the latter. "mutable double*" is declaring the pointer
as mutable. "double mutable*" would be declaring the data pointed to as
mutable, which strikes me as odd because it already is!

No. Mutable is a storage class specifier. It always modifies
what is being declared, and can only appear in the
decl-specifier-seq; there is no way of declaring what is pointed
to as mutable. (Note that moving a "const" like this doesn't
change anything either.)
 
P

Paul Bibbings

I'd need a complete, compilable example to say more.  There's
nothing in what you've posted to explain the behavior you're
describing, and I'm very, very sceptical that it is due to
a compiler error.

I'm coming in a little late on this one but still, I would agree with
James here. We really need to see a *complete* example (i.e., no
ellipses and with a suitable invocation from main) that we can build
and run and which, when compiled with VS2005, actually generates the
error that you are encountering.

Regards

Paul Bibbings
 
F

Francesco S. Carta

on 06/07/2010 14:53:09 said:
I tried declaring x and data with mutable. That worked for data. But
when I tried declaring x as

mutable double* x;

it compiled, but resulted in a runtime "write to protected memory"
error inside costFunction. I then tried

double* mutable x;

which worked, but why that and not the other?

As it seems from other replies, this is likely a compiler specific
problem, because those two declaration should be interpreted as having
the same exact meaning.

Besides, I tried something similar somewhere else, read below the
following code please:

//-------
struct Test {
int datum;
mutable int mutable_datum;
int* ptr;
mutable int* mutable_ptr;
Test() :
datum(42),
mutable_datum(42),
ptr(&mutable_datum),
mutable_ptr(&datum) {}
};

int main() {

const Test t;

// directly modify data

// fails, OK
// t.datum = 10;

// works, OK
t.mutable_datum = 10;

// indirectly modify data:

// works, OK
*t.ptr = 10;

// works, NOT OK?
*t.mutable_ptr = 10;

// modify pointers:

// fails, OK
// t.ptr = &t.datum;

// works, OK
t.mutable_ptr = &t.mutable_datum;

return 0;
}
//-------

"fails" stands for "does not compile", "works" stands for "compiles and
runs with no runtime error" - I tested it with MinGW 4.4.0.

The line that reads "NOT OK?" seems like it is casting away the const
that should be attached to "data" - I have no idea if the standard
mandates, allows, forbids or simply doesn't tell anything about cases
like this.

Could you make some test on your compiler modifying my code and check
whether you get the same error you got on your code?
 
J

James Kanze

As it seems from other replies, this is likely a compiler
specific problem, because those two declaration should be
interpreted as having the same exact meaning.

It's more likely that he changed something else in his code at
the same time. I made a quick trial with VS 2005, and there was
no difference between the two in the generated code.
Besides, I tried something similar somewhere else, read below
the following code please:
//-------
struct Test {
int datum;
mutable int mutable_datum;

Allows changing the int even through a const lvalue expression.
int* ptr;
mutable int* mutable_ptr;

Allows changing the pointer even through a const lvalue
expression.
Test() :
datum(42),
mutable_datum(42),
ptr(&mutable_datum),
mutable_ptr(&datum) {}

};
int main() {
const Test t;
// directly modify data
// fails, OK
// t.datum = 10;
// works, OK
t.mutable_datum = 10;
// indirectly modify data:
// works, OK
*t.ptr = 10;
// works, NOT OK?
*t.mutable_ptr = 10;

This is undefined behavior. In practice: if the object doesn't
have static lifetime (your object has auto lifetime), has
a non-trivial constructor or destructor (your object has
a non-trivial constructor), has any mutable members, or any of
the initializers are not constant expressions, the code will
"work". If you wrote something like:

struct Toto
{
int a;
int* p;
};
Toto const t = { 42, &t.a };

at namespace scope, and tried:
*t.p = 10;
you would likely get a runtime error with some compilers.

Not a compile time error. The compiler is not required to do
the necessary analysis. And the restrictions which result in
a runtime error correspond to the restrictions necessary in
practice for the compiler to place the object in read-only
memory. Modern systems don't have any provision for changing
the protection of a very small block of memory dynamically.
The object cannot be write protected during construction or
destruction, and of course, dynamically allocated memory or
memory on the stack must come from a non-write-protected pool
(and write protecting an object with a mutable member would have
to somehow ensure that the mutable member wasn't
write-protected).

Note too that this is why I would hesitate with statements along
the lines of "a const function may not modify non-mutable
members". In this case, a const member function could still do
++*mutable_ptr, effectively modifying a non-mutable member.
// modify pointers:
// fails, OK
// t.ptr = &t.datum;
// works, OK
t.mutable_ptr = &t.mutable_datum;
return 0;}
//-------
"fails" stands for "does not compile", "works" stands for
"compiles and runs with no runtime error" - I tested it with
MinGW 4.4.0.
The line that reads "NOT OK?" seems like it is casting away
the const that should be attached to "data" - I have no idea
if the standard mandates, allows, forbids or simply doesn't
tell anything about cases like this.

Mutable and const are largely compile time concepts, and (as far
as the compiler is concerned) only affect the basic object.
There's no "casting away" of const; the pointer was initialized
before const took effect.
Could you make some test on your compiler modifying my code
and check whether you get the same error you got on your code?

I'd be very surprised if any compiler behaves differently than
what you've observed.
 
F

Francesco S. Carta

Mutable and const are largely compile time concepts, and (as far
as the compiler is concerned) only affect the basic object.
There's no "casting away" of const; the pointer was initialized
before const took effect.

I suspected that the mutable keyword was something tied to compile time
and not to the run time - quite in the spirit of C++.

Your explanation made all of it decisively clearer, thanks a lot.
 
Ö

Öö Tiib

The suggestion that nothing mutate the state of the object is
*not* a language issue, but simply a convention.  The language
doesn't no anything about the state of the object, as such.

There is (or was once---I'm not sure if it survived
standardization) a rule which says that if the actual object is
const, and you attempt to modify it, the code has undefined
behavior (unless the object has user defined
constructors?---that was the original rule).  I'm not sure what
the rule is concerning the modification of a temporary object.
But none of that is really relevant here, because as far as the
language is concerned, only the pointers are part of the object,
and not what they point to.

Yes, there are restrictions mentioning undefined behavior in standard
about writing into const object (and also into its storage location
that it occupied before destruction) when that const object has
automatic or static storage. Not sure, but it feels like for example
const data members of dynamically allocated objects may be even
modified without having undefined behavior.
 
S

Stuart Redmann

I'm using a third party library that requires me to implement the
virtual operator

class CostFunctor
{
double operator()(const std::vector<double>& v) const {
...
}

double* x;
int dimx;
MyData* data;

}

Within this operator, I need to change the implementation to delegate
to a C function,

void costFunction(double *v, int dimv, double *x, int dimx, void
*data);

costFunction doesn't change v, does change x, and also changes data
(after casting back to MyData*.).
[snip]

Any comments on the safest way of implementing this interface would be
appreciated (it's not possible to modify the interface of CostFunctor
or the signature of costFunction.)

The only thing relevent about the interface is the signature of
operator(), but more concretely ...

class ICostFunctor
{
public:
virtual double operator()(const std::vector<double>& v) const =
0;

};


So the interface says that your Cost Functor should stay constant when
being used, IOW using it should no change its internal state. I can't
imagine what the rationale behind this decision should be, but maybe
there _is_ a quite good reason.

This leads to the question of why your functor requires some internal
state? Does the C-function costFunction actually read the parameters x
and data, or is it just writing to it? If the later were the case, you
could simply change the members variables to local variables:

class CostFunctor
{
double operator()(const std::vector<double>& v) const
{
// Provide memory for return values of costFunction (either
// an statically sized array, or allocate it dynamically).
double x[100];

costFunction(const_cast<double*>&v[0],
v.size(),
x,
sizeof(x)/sizeof(double),
data); // Need to handle this as well, but I don't
know
// how data is exactly used.
}
};

Regards,
Stuart
 

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

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,736
Latest member
AdolphBig6

Latest Threads

Top