Topic: Reducing free variables by using const


Author: "Bill Wade" <bill.wade@stoner.com>
Date: 1999/01/14
Raw View
>The question is: Is there a way to either modify this "const-block"
>construct, or another *simple and readible" way of achieving this form of
>const.

int i;    // Non const
{
  const int& ci = i;
  const int& i = ci;  // i is const for the rest of this block
}
---
[ 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: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/01/15
Raw View
Paul Sorensen wrote:
>
> I always try to keep the number of free (ie. "non-const") variables by using
> the various forms of the const keyword.  One thing C++ currently doesn't
> support is to make an object const within a block....this is useful when
> const is unavailable for some reason and yet there is code in which a
> variable should be constant.
>
> A few months ago I proposed the idea of a "const block" defined as:
>
> const <name list> { <statement-block> }
>
> which takes all the names in <name-list> and makes them constants within
> <statement-block>.
>
> The most obvious example of the use of this is something like:
>
> for (int i = 0; i < 10; ++i) const i
> {
>     // i is constant in here
> }
>

[...]

> The question is: Is there a way to either modify this "const-block"
> construct, or another *simple and readible" way of achieving this form of
> const.

Well, you can hide the variable with a reference to const to it.
However, the "obvious" syntax for this won't work, since the reference
is visible (and hiding the variable) already in its own initializer.

But the following will work:

for(int i=0; i<10; ++i)
{
  int const& i_ref=i; // make i accessible before hiding it
  int const& i=i_ref; // hide i

  i=5; // Error: attempt to modify object through const access path
}

Now, I agree it's not quite readable; however, in this case
a macro might help:

#define CONST(type, var) \
  type const& ref_x##var##x=var; \
  type const& var=ref_x##var##x;

Then you can just write

int some_var;

{
  CONST(int, some_var);

  some_var = 5; // error
}

If you have a compiler which has typeof (f.ex. g++), you can even
remove the type parameter by replacing type with typeof(var)
in the macro.


[ 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@wedgewood.net>
Date: 1999/01/13
Raw View
I always try to keep the number of free (ie. "non-const") variables by using
the various forms of the const keyword.  One thing C++ currently doesn't
support is to make an object const within a block....this is useful when
const is unavailable for some reason and yet there is code in which a
variable should be constant.

A few months ago I proposed the idea of a "const block" defined as:

const <name list> { <statement-block> }

which takes all the names in <name-list> and makes them constants within
<statement-block>.

The most obvious example of the use of this is something like:

for (int i = 0; i < 10; ++i) const i
{
    // i is constant in here
}

This is also useful in cases where it takes a few lines to build the value
of a variable - and then that variable being considered constant for a block
of statement:

myClass x;
x.operation1();
x.operation2();
const x
{
    // x is now set and is constant here
}

The main problem with this construct is that it creates the following
inconsistency:

int x = 5;
int* y = &x;
const x
{
    a = x;
    *y = 3;
    b = x;
    // a == 5 but b == 3!!!
}

There are already these kinds of inconsistencies possible in C++ - but not
as easy to reproduce as this one.  "const" is really only a directive to the
compiler - not something which can't be circumvented. One example:

void foo(const int b, int* c)
{
    *c = b*b;
    // if called as below, b will suddenly change value even though it's a
constant
}

int main()
{
    int a = 5;
    foo(a,&a);
    // now a == 25
}


The question is: Is there a way to either modify this "const-block"
construct, or another *simple and readible" way of achieving this form of
const.

Thanks in advance for any suggestions or comments.

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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: sbnaran@localhost.localdomain.COM (Siemel Naran)
Date: 1999/01/13
Raw View
On 13 Jan 99 14:30:57 GMT, Paul Sorensen <psorensen@wedgewood.net> wrote:

>The most obvious example of the use of this is something like:
>
>for (int i = 0; i < 10; ++i) const i
>{
>    // i is constant in here
>}

This is a good idea.  In some ways, it seems a little like safety
taken too far.

BTW, local classes which can access the local context would be
good here.  Eg,

void f()
{
   Thing t;
   struct Loop : public __local_context
   {
      void operator()(int i); // can use 't'
   };

   for (int i=0; i<10; ++i) Loop()(i);
}


>This is also useful in cases where it takes a few lines to build the value
>of a variable - and then that variable being considered constant for a block
>of statement:
>
>myClass x;
>x.operation1();
>x.operation2();
>const x
>{
>    // x is now set and is constant here
>}

Fine, but same comments as above.


>The main problem with this construct is that it creates the following
>inconsistency:
>
>int x = 5;
>int* y = &x;
>const x
>{
>    a = x;
>    *y = 3;
>    b = x;
>    // a == 5 but b == 3!!!
>}

This inconsistency is not a problem because C++ already has this
inconsistency.  Eg,
   void f(const int& x, int& y);
where 'x' and 'y' might be the same object.

>There are already these kinds of inconsistencies possible in C++ - but not
>as easy to reproduce as this one.  "const" is really only a directive to the
>compiler - not something which can't be circumvented. One example:

OK, you've observed the above.  Anyway, supposing your 'const' rule
were adopted, the example above seems unlikely to occur in practice.


--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------


[ 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: Barry Margolin <barmar@bbnplanet.com>
Date: 1999/01/14
Raw View
In article <77h4n0$h91$1@remarQ.com>,
Paul Sorensen <psorensen@wedgewood.net> wrote:
>I always try to keep the number of free (ie. "non-const") variables by using
>the various forms of the const keyword.  One thing C++ currently doesn't
>support is to make an object const within a block....this is useful when
>const is unavailable for some reason and yet there is code in which a
>variable should be constant.

What's the purpose of this declaration?  To produce warnings if you try to
modify the object within the block, or help the optimizer by declaring that
an object won't change?  In the latter case, traditional data flow analysis
should allow the compiler to determine that the object doesn't change, so
it should be able to keep it in a register; that's commonly done for
iteration variables, as in your for-loop example.

>void foo(const int b, int* c)
>{
>    *c = b*b;
>    // if called as below, b will suddenly change value even though it's a
>constant
>}
>
>int main()
>{
>    int a = 5;
>    foo(a,&a);
>    // now a == 25
>}

b shouldn't change value.  C uses call by value (unless a paramter is a
reference), so foo's b variable must not share storage with main's a.  The
const modifier does not change this, precisely because of problems like
this example.

--
Barry Margolin, barmar@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Don't bother cc'ing followups to me.
---
[ 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              ]