Topic: const" as a verb


Author: Christopher Eltschka <celtschk@web.de>
Date: Wed, 3 Apr 2002 20:16:33 GMT
Raw View
Team Hyer <teamhyer@yahoo.com> writes:

> hyrosen wrote:
> >
> > Team Hyer wrote:
> > >     Vector v;
> > >     Matrix m;
> > >     nasty_function(lots_of_args, &v, &m);
> > >     const v, m;
> >
> > Completely unnecessary, given that you can just do
> >
> >  const Vector &cv = v;
> >  const Matrix &cm = m;
>
>   Or I could just write nothing at all -- obviously v
> and m will already grant me const access.  What I'd
> like is to remove the possibility of non-const access.
>
>   It's possible to get it like this:
>
>     auto_ptr<const Vector> capv;
>     auto_ptr<const Matrix> capm;
>     {
>         auto_ptr<Vector> apv(new Vector);
>         auto_ptr<Matrix> apm(new Matrix);
>         nasty_function(lots_of_args, v.get(),
> m.get());
>         capv = auto_ptr<const Vector>(apv.release());
>         capm = auto_ptr<const Matrix>(apm.release());
>     }
>     const Vector& v = *capv.get();
>     const Matrix& m = capm.get();
>
>   But that's kind of ugly.

The following is still not perfect, but less ugly:

Vector foo()
{
  struct init
  {
    Vector v;
    Matrix m;
    init() { nasty_function(lots_of_args, v.get(), m.get()); }
  } local;

  return local.m * local.v;
}

One thing I don't like with your proposal is that IMHO it's backwards:
Your variables are indeed meant to be const, except for
initialisation. However, with your feature, they are declared
non-const, except after "constifying".

Maybe a better solution would be an initialize construct:

  Vector const v;
  Matrix const m;

  initialize (v, m)
    nasty_function(lots_of_args, v.get(), m.get());

initialize would be a control statement where inside the controlled
statement (which may of course be a block statement) the const
variables mentioned in its argument list are non-const (so they can be
initialized). Probably it would be a good idea to restrict the
arguments to variables in the same scope as the initialize construct
itself.

To avoid adding a new keyword, the keyword mutable could be reused:

  Vector const v;
  Matrix const m;

  mutable (v, m) // would be an error in current C++
  {
    nasty_function(lots_of_args, v.get(), m.get());
  }

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Team Hyer <teamhyer@yahoo.com>
Date: Wed, 13 Feb 2002 17:21:56 GMT
Raw View
hyrosen wrote:
>
> Team Hyer wrote:
> >     Vector v;
> >     Matrix m;
> >     nasty_function(lots_of_args, &v, &m);
> >     const v, m;
>
> Completely unnecessary, given that you can just do
>
>  const Vector &cv = v;
>  const Matrix &cm = m;

  Or I could just write nothing at all -- obviously v
and m will already grant me const access.  What I'd
like is to remove the possibility of non-const access.

  It's possible to get it like this:

    auto_ptr<const Vector> capv;
    auto_ptr<const Matrix> capm;
    {
        auto_ptr<Vector> apv(new Vector);
        auto_ptr<Matrix> apm(new Matrix);
        nasty_function(lots_of_args, v.get(),
m.get());
        capv = auto_ptr<const Vector>(apv.release());
        capm = auto_ptr<const Matrix>(apm.release());
    }
    const Vector& v = *capv.get();
    const Matrix& m = capm.get();

  But that's kind of ugly.

-- Tom Hyer



__________________________________________________
Do You Yahoo!?
Send FREE Valentine eCards with Yahoo! Greetings!
http://greetings.yahoo.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: raczy@beer.com (Chewie)
Date: Thu, 14 Feb 2002 15:55:21 GMT
Raw View
Team Hyer <teamhyer@yahoo.com> wrote
> hyrosen wrote:
> >
> > Team Hyer wrote:
> > >     Vector v;
> > >     Matrix m;
> > >     nasty_function(lots_of_args, &v, &m);
> > >     const v, m;
> >
> > Completely unnecessary, given that you can just do
> >
> >  const Vector &cv = v;
> >  const Matrix &cm = m;
>
>   Or I could just write nothing at all -- obviously v
> and m will already grant me const access.  What I'd
> like is to remove the possibility of non-const access.
>
>   It's possible to get it like this:
>
>     auto_ptr<const Vector> capv;
>     auto_ptr<const Matrix> capm;
>     {
>         auto_ptr<Vector> apv(new Vector);
>         auto_ptr<Matrix> apm(new Matrix);
>         nasty_function(lots_of_args, v.get(),
> m.get());
>         capv = auto_ptr<const Vector>(apv.release());
>         capm = auto_ptr<const Matrix>(apm.release());
>     }
>     const Vector& v = *capv.get();
>     const Matrix& m = capm.get();
>
>   But that's kind of ugly.

kind of. But the solution doesn't seem so far. As this is
C++, you can encapsulate the messy part inside a class,
rather than just putting into an inner block.
For instance:

class Initializer {
  Vector m_v;
  Matric m_m;
public:
  Initializer(lots_of_args) {
    nasty_function(lots_of_args, m_v, m_m);
  }
  const Vector &getVector() const {return m_v;}
  const Matrix &getMatrix() const {return m_m;)
};

No more need for a "const as a verb" or "finalize" or whatever.
Or did i miss something?
--
Come Raczy

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Richard Smith" <richard@ex-parrot.com>
Date: Thu, 14 Feb 2002 15:56:36 GMT
Raw View
"Hyman Rosen" <hyrosen@mail.com> wrote in message
news:3C683894.8030307@mail.com...
> Team Hyer wrote:
> >     Vector v;
> >     Matrix m;
> >     nasty_function(lots_of_args, &v, &m);
> >     const v, m;
>
> Completely unnecessary, given that you can just do
>
> const Vector &cv = v;
> const Matrix &cm = m;

And if you want to hide the outer name completely, you could do

    Vector v;
    Matrix m;

    nasty_function( lots_of_args, &v, &m );

    {
      const Vector &cv = v;
      const Vector &v = cv;
      const Matrix &cm = m;
      const Matrix &m = cm;

      // ...
    }


--
Richard Smith


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Balog Pal" <pasa@lib.hu>
Date: Thu, 14 Feb 2002 17:22:13 GMT
Raw View
"Chewie" <raczy@beer.com> wrote in message news:c0aa8210.0202132059.2832c1f1@posting.google.com...

> No more need for a "const as a verb" or "finalize" or whatever.
> Or did i miss something?

Yes, you completely miss the point.

The code should be readable and followable, and also safe.

What you propose as 'solution' is a big step toward obfuscation.  In the good case where you did it all correctly -- in real life situation you'll also likely introduce a new source of bugs.

Paul


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Team Hyer <teamhyer@yahoo.com>
Date: Mon, 11 Feb 2002 18:17:04 GMT
Raw View
I would like to propose the following (relatively
minor) change to C++, which I think would help make
the "const" qualifier more useful for finding coding
errors, by allowing it to be added on the fly.

MOTIVATION
----------

    Often a value is filled by a complex routine, and
almost as often more than one value is populated by
the same routine.
    For example:


    Vector v;
    Matrix m;
    nasty_function(lots_of_args, &v, &m);
    // Lots more computations using v and m...


    Now it may well be that v and m are not changed
after once being populated.  However, due to the
manner in which they were created, they cannot be
declared const.  Adding the "const as verb" syntax
would let us write:

    Vector v;
    Matrix m;
    nasty_function(lots_of_args, &v, &m);
    const v, m;


    This would declare that v and m (and by extension,
any references to them which might be created later)
would be const for the remainder of the routine.
However, note that if non-const references had already
been created, they would still allow non-const access:

    //...
    nasty_function(lots_of_args, &v, &m);
    Matrix& rm = m;
    Vector::iterator i = v.begin();
    const v, m;
    // i and rm allow non-const access to v and m; but
v and m cannot be used to create non-const accessors


    Consider what happens if the const is applied
inside a loop or conditional:

    //...
    nasty_function(lots_of_args, &v, &m);
    if (runtime_condition) {
 const v, m;
    }

    Thus the statement "const v, m" must disallow
non-const access to v and m only for the remainder of
the
scope in which that statement appears.

PROPOSAL
--------

 Insert the following paragraph and examples at the
end of Section 7.1.5.1 ("The cv-qualifiers"), after
paragraph 8:

 An object may be "requalified" to a more qualified
type (3.9.3) after its definition.  Within the scope
of the requalification, no later program statement may
access the object in a manner not allowed by this more
qualified type.

    [Example:

        int i;          // i is not const
 std::cin << i; // modifies i
        const i; // i will hereafter allow only const
access
        ++i;     // ill-formed:  attempt to modify
const

    For another example

        class X {
            public:
                static void mutate(std::vector<int>*
v); // alters v
        };
        std::vector<int> v;
        X::mutate(&v);     // OK: changes v
        std::vector<int>::iterator p = v.begin();
        while (v.front() != 0) {
            const v; // disallow non-const access to v
within the scope of while(...)
            *p = 0; // but existing accessors are
still valid
        }
        v.clear(); // OK: v has not been requalified
in this scope

 --end example]




Any comments are welcome.

-- Tom Hyer


__________________________________________________
Do You Yahoo!?
Send FREE Valentine eCards with Yahoo! Greetings!
http://greetings.yahoo.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Balog Pal" <pasa@lib.hu>
Date: Mon, 11 Feb 2002 21:48:59 GMT
Raw View
"Team Hyer" <teamhyer@yahoo.com> wrote in message news:20020211140132.90934.qmail@web12406.mail.yahoo.com...

> I would like to propose the following (relatively
> minor) change to C++, which I think would help make
> the "const" qualifier more useful for finding coding
> errors, by allowing it to be added on the fly.

Wow, that's my finalize proposal :).

I suggested the same maybe 2 years ago on clcm.
You may look up subjects 'making const when the value is final' and 'The finalize proposal'.

My version was somewhat different than yours, not only in the keyword (overloading keyword 'const' for that purpose would be pretty messy -- use finalise, finalize, makeconst, or something like that!).

For one, I defined it working for pointers too.

- -----
Type t;  // object
Type &rt = t;  // reference
Type * pt; // pointer
Type **** ppppt; // multiple level pointer

using the finalize would change the type as it had been originally declared
as

// keyword        // the new type of the variable

finalize t;     //    const Type t;
finalize rt;    //    const Type & t;
finalize pt;    //    Type * const t;
finalize *pt;    //    const Type * t;
finalize ****pppt;    //    Type const **** t;
finalize ***pppt;    //    Type *const *** t;
finalize ****pppt, ***pppt;   // Type const * const * * * t;
- -----

>     Thus the statement "const v, m" must disallow
> non-const access to v and m only for the remainder of
> the
> scope in which that statement appears.

That was the other difference in my proposal -- and probably that was why it didn't gain support. IMHO to make it really useful, finalize should propagate to scopes outside its current scope, until you're in the fuction, or the original object disappears.  Without that it hardly does much useful work: you either have to pay attention and place it to the scope level the object was originally defined -- what may be well after the point it reached the final value. Or if you place it there, you'll lose the constifying effect at the next }, where the object still exists, and should be protected further.

> Insert the following paragraph and examples at the
> end of Section 7.1.5.1 ("The cv-qualifiers"), after
> paragraph 8:
>
> An object may be "requalified" to a more qualified
> type (3.9.3) after its definition.

I'd think that twice. what makes sense for const doesn't necessarily makes sense for volatile!

Paul

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Hyman Rosen <hyrosen@mail.com>
Date: Mon, 11 Feb 2002 22:04:58 GMT
Raw View
Team Hyer wrote:
>     Vector v;
>     Matrix m;
>     nasty_function(lots_of_args, &v, &m);
>     const v, m;

Completely unnecessary, given that you can just do

 const Vector &cv = v;
 const Matrix &cm = m;

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]