Topic: const blocks


Author: "Paul Sorensen" <psorensen@bigpond.com>
Date: 1998/02/04
Raw View
Lewis Preston Thomas wrote in message ...
>It should be possible to use a constant reference inside a scope. It
>is a bit ugly, and it might take a tiny performance hit, but it would do
>what you want.
>
>Footype foo;
><initialize foo>
>{
> const Footype & cfoo = foo;
> const Footype & foo = cfoo;
> <error to modify foo>
>}

I think I'll give that a go for a while and see if I can get into the habit
of writing the extra couple of assignments...thanks.

I'm still interested in hearing comments on whether, given these useful
work-arounds, people think that a block qualifier of the form "const <id
list> { <statement-list> }" is worth consideration.

Thanks
Paul Sorensen
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Paul Sorensen" <psorensen@bigpond.com>
Date: 1998/02/04
Raw View
Hi again,

I realised at work what is probably the most common case where a const block
would be useful.  In 90% of "for" loops, the loop variable is not expected
to be modified inside the loop. Here is a rather contrived example using an
STL vector of integers.
vector<int> integers;
...
(integers is populated in here)
...
// increment each element of 'integers'
for (vector<int>::iterator i = integers.begin(); i != integers.end(); ++i)
{
    *i++;
}

I havent actually tried this, but if my reading of the C++ operator
precedence table is correct then this code would do absolutely nothing
(other than move 'i' through 'integers' twice as fast as expected).  In most
compilers it probably wouldn't even cause a 'statement has no effect'
warning because something is in fact incremented.

If the for loop used a const block modifier, like this:

for (vector<int>::iterator i = integers.begin(); i != integers.end(); ++i)
const i
{
    *i++;
}

Then a compiler error would result and the user would hopefully realise that
they should change '*i++', to something like '++(*i)';
Regards
Paul Sorensen
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1998/02/04
Raw View
Paul Sorensen wrote:
>
> Lewis Preston Thomas wrote in message ...
> >It should be possible to use a constant reference inside a scope. It
> >is a bit ugly, and it might take a tiny performance hit, but it would do
> >what you want.
> >
> >Footype foo;
> ><initialize foo>
> >{
> > const Footype & cfoo = foo;
> > const Footype & foo = cfoo;
> > <error to modify foo>
> >}
>
> I think I'll give that a go for a while and see if I can get into the habit
> of writing the extra couple of assignments...thanks.
>
> I'm still interested in hearing comments on whether, given these useful
> work-arounds, people think that a block qualifier of the form "const <id
> list> { <statement-list> }" is worth consideration.

The above work-arround doesn't let the compiler optimise
foo as a constant. With the const block, the following
would cause undefined behaviour:

int i = 4;
int &ri = i;
constify (i){
    // i++; // ill-formed
    ri++; // well-formed, undefined behaviour
    cout << i;
}

I am not sure that your idea is good, but it's interresting
to consider it.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Lewis Preston Thomas <lpt@acpub.duke.edu>
Date: 1998/02/04
Raw View
On 4 Feb 1998, Valentin Bonnard wrote:

> > >
> > >Footype foo;
> > ><initialize foo>
> > >{
> > > const Footype & cfoo = foo;
> > > const Footype & foo = cfoo;
> > > <error to modify foo>
> > >}
>
> The above work-arround doesn't let the compiler optimise
> foo as a constant. With the const block, the following
> would cause undefined behaviour:
>
> int i = 4;
> int &ri = i;
> constify (i){
>     // i++; // ill-formed
>     ri++; // well-formed, undefined behaviour
>     cout << i;
> }
>
> I am not sure that your idea is good, but it's interresting
> to consider it.
>

The optimizing problem I believe is that either
A. non-const references to an object would result in undefined behavior or
B. a const cannot be fully optimized when a non-const reference to it is
used.

 The dilemma of choosing between A and B appears to be necessary.
If it can be determined that in a block of code no non-const references
to foo exists, or no non-const reference that exists is used, then
safe optimization may occur.

 If it could be determined that there were no non-const references
to an object foo used inside a const block, the extension should allow
compilers to optimize foo as a constant. Shouldn't the same be true in
the workaround solution? True there are two const references to foo, but
if there are no valid non-const references the compiler should be able to
optimize foo as a constant. In theory might it even be possible that the
cfoo reference and assignment be optimized out of existence if it is only
used as a temporary to initialize foo?

Lewis Thomas
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: David R Tribble <david.tribble@central.beasys.com>
Date: 1998/02/04
Raw View
Paul Sorensen wrote:
> I am interested to hear what people think of a possible new C++
> enhancement.
>
> I would like to see a const "block qualifier" of the form:
> const <Identifer list>
> {
>     <statement block>
> }
>
> That way I could code the above as:
> int foo;
> <a few lines to initialise foo>
> const foo
> {
>     <it's an error to modify foo in here>
> }

Java does something like this; a class can have a 'static' block
that executes prior to any constructors for the class (presumably
at program startup), which allows non-trivial initializations and
the like for the class.  It's sort of like a static member function
of the class but doesn't have a name.

I think it would be a clean extension to future C++.  Possible
syntax, borrowing from Java, could be:

    // Syntax 1
    class Foo
    {
    private:    // private by default
        static  // no name
        {
            ...initialization code goes here...
        };

        ...other members...
    };

If you're like me, you don't approve of placing code within header
files, so the above isn't quite satisfactory.  (Java gets away with
it because it doesn't use (or need) header files.)  So a better
syntax is:

    // Syntax 2
    class Foo
    {
    private:
        static Foo() static;  // Looks like a constructor, but static

        ...other members...
    };

And the source (non-header) file could have the actual code for the
static class initializer:

    Foo::Foo() static
    {
        ...initialization code for class Foo...
    };

The "static constructor" or "static class initializer" function
must have an explicit trailing 'static' specifier (similar to a
'const' class method specifier).  (Yet one more meaning for the
word 'static'!)  The function would take no arguments.  It cannot
be called explicitly (implying that it's a good idea to declare
it 'private'), but is invoked implicitly sometime during program
startup prior to the execution of ::main(), or at least prior to
the execution of any constuctors for the class.


-- David R. Tribble, david.tribble@noSPAM.central.beasys.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Paul Sorensen" <psorensen@bigpond.com>
Date: 1998/02/02
Raw View
Hi,

I am interested to hear what people think of a possible new C++ enhancement.

I like to minimise the number of free variables in any given piece of code.
At the moment there are several mechanisms:

    - const methods
    - const members (initialised during construction)
    - const parameters
    - plain old constant variables

In trying to maintain this habit, it's always with a tinge of regret when I
find the need to code something like:

int foo;
<a few lines of code to initialise foo, too complex to try to do in one line
so that a const can be used>
<a block of lines which shouldn't modify foo>

I would like to see a const "block qualifier" of the form:

const <Identifer list>
{
    <statement block>
}

That way I could code the above as:

int foo;
<a few lines to initialise foo>
const foo
{
    <it's an error to modify foo in here>
}

Regards

Paul Sorensen
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Bjorn Fahller <Bjorn.Fahller@ebc.ericsson.se>
Date: 1998/02/02
Raw View
Paul Sorensen wrote:

> In trying to maintain this habit, it's always with a tinge of regret when I
> find the need to code something like:
>
> int foo;
> <a few lines of code to initialise foo, too complex to try to do in one line
> so that a const can be used>
> <a block of lines which shouldn't modify foo>

A simple work around is to split your function in two:

namespace {
  inline int foo_initializer(whatever)
  {
  < your few lines of code that calculates the value to be used
    and returns it. >
  }
}

real_function(whatever)
{
  const int foo=(foo_initializer(whatever));
  < your block of lines that don't modify foo>
}

Note that since foo_initializer is in the nameless namespace it doesn't
pollute the global namespace at all, and most probably it's short and
simple enough to be easily inlined by your compiler, even though it
takes enough many statements to be a problem to inline the const
ininitalization by hand.

> I would like to see a const "block qualifier" of the form:

Maybe, but not necessary. In fact, your suggestion and mine above are
as far as I can see synonymous (functionality wise.) It's just the
syntax that differs.
  _
/Bjorn.
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Irmantas Naujikas" <irnauj@puni.osf.lt>
Date: 1998/02/02
Raw View
Hi,

>I like to minimise the number of free variables in any given piece of
>code.

So do I.

>int foo;
><a few lines to initialise foo>
>const foo
>{
>    <it's an error to modify foo in here>
>}

which compiler support this ?





[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Barry Margolin <barmar@bbnplanet.com>
Date: 1998/02/02
Raw View
In article <6b4o5m$ian$1@trimpas.omnitel.net>,
Irmantas Naujikas <irnauj@puni.osf.lt> wrote:
>which compiler support this ?

None, it's a language enhancement he's proposing.

--
Barry Margolin, barmar@bbnplanet.com
GTE Internetworking, Powered by BBN, Cambridge, MA
Support the anti-spam movement; see <http://www.cauce.org/>
Please don't send technical questions directly to me, post them to newsgroups.


[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Paul Sorensen" <psorensen@bigpond.com>
Date: 1998/02/03
Raw View
Bjorn Fahller wrote in message <34D5C876.1D68A824@ebc.ericsson.se>...

>A simple work around is to split your function in two:
>...

Thanks for the reply.  This technique is a great idea, especially where the
initialisation is reasonably complex.  I'm unfortunately still using a
compiler which doesnt support namespaces so I don't have much experience
with them.


>In fact, your suggestion and mine above are
>as far as I can see synonymous (functionality wise.) It's just the
>syntax that differs.

Yes they are.  Although I'd make a few points relevant when the
initialisation is simple, but where I'd still want to do it in a few lines
for the sake of readability.

- the initialisation is removed from the surrounding context and the intent
would be confusing to a future reader of the code.  They might say "why did
the programmer do all this when the initialisation is only called in one
place and is simple enough to write in the function".  Basically all the
source 'noise' reduces the readability of the program.

- the overhead (in terms of source code) is probably enough to deter the
programmer from using this mechanism except where the code is critical.  The
other uses of const (and I think the one that I've proposed) are convenient
enough that they can become a good programming habit.

Regards
Paul Sorensen
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Oleg Zabluda <zabluda@math.psu.edu>
Date: 1998/02/03
Raw View
Paul Sorensen <psorensen@bigpond.com> wrote:
: Hi,

: I am interested to hear what people think of a possible new C++ enhancement.

: I like to minimise the number of free variables in any given piece of code.
: At the moment there are several mechanisms:

:     - const methods
:     - const members (initialised during construction)
:     - const parameters
:     - plain old constant variables

: In trying to maintain this habit, it's always with a tinge of regret when I
: find the need to code something like:

: int foo;
: <a few lines of code to initialise foo, too complex to try to do in one line
: so that a const can be used>
: <a block of lines which shouldn't modify foo>

: I would like to see a const "block qualifier" of the form:

: const <Identifer list>
: {
:     <statement block>
: }

: That way I could code the above as:

: int foo;
: <a few lines to initialise foo>
: const foo
: {
:     <it's an error to modify foo in here>
: }

I always wanted something along these lines, with a usable syntax.

Here are some ways you can achieve this effect within current C++:

1.

class hide{};

int foo;
{
 const int& const_foo = foo;
 hide foo; // Some syntactic sugar never hurts.

 // Now you can only access the original foo through const_foo
} // const_foo is out of scope, int foo is visible again.

2.

// int foo; <<== this where you wanted it to be.
const struct /*unnamed*/ {
 int operator()() const { // or make it operator int(), if you want
  int foo;
  // <a few lines to initialise foo>
  return foo;
 }
} initialize_foo; // initialize_foo has the same scope as foo.

const int foo = initialize_foo(); // <<== this is where you
                                  // actually put it.

This particular one makes foo const forever.

3. Combination of the two above + variation on the singleton pattern:

// Some preparation in advance is needed
int& foo_instance()
{
   static int foo;
   return foo;
}

//.....

// int foo; <<== this where you wanted it to be.
int& foo = foo_instance(); // This is what you do instead.
// <a few lines to initialise foo>
{
 const int& foo = foo_instance();
 // foo is const here
 {
   int& foo = foo_instance();
   // foo is mutable again
 }
 // foo is const again.
}

Oleg.
--
Life is a sexually transmitted, 100% lethal disease.


[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Pete Becker <petebecker@acm.org>
Date: 1998/02/03
Raw View
Paul Sorensen wrote:
>
> Bjorn Fahller wrote in message <34D5C876.1D68A824@ebc.ericsson.se>...
>
> >A simple work around is to split your function in two:
> >...
>
> Thanks for the reply.  This technique is a great idea, especially where the
> initialisation is reasonably complex.  I'm unfortunately still using a
> compiler which doesnt support namespaces so I don't have much experience
> with them.

Dont' be thrown off by the use of the namespace in that example. The
idea was to write a function to compute the initial value. The namespace
is added sugar. Maybe useful, but not necessary.
 -- Pete



[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Lewis Preston Thomas <lpt@acpub.duke.edu>
Date: 1998/02/03
Raw View
On 2 Feb 1998, Paul Sorensen wrote:

> In trying to maintain this habit, it's always with a tinge of regret when I
> find the need to code something like:
>
> int foo;
> <a few lines of code to initialise foo, too complex to try to do in one line
> so that a const can be used>
> <a block of lines which shouldn't modify foo>
>
> I would like to see a const "block qualifier" of the form:
>
> const <Identifer list>
> {
>     <statement block>
> }
>
> That way I could code the above as:
>
> int foo;
> <a few lines to initialise foo>
> const foo
> {
>     <it's an error to modify foo in here>
> }

It should be possible to use a constant reference inside a scope. It
is a bit ugly, and it might take a tiny performance hit, but it would do
what you want.

Footype foo;
<initialize foo>
{
 const Footype & cfoo = foo;
 const Footype & foo = cfoo;
 <error to modify foo>
}
It does add another const reference to foo, and requires reference
access, but this would enforce constness with current compilers.

Lewis Thomas
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]