Topic: Lack of const correctness in C++ standard?


Author: david@kai.com (David C. Nelson)
Date: 1998/06/17
Raw View
If you use a compiler that is following the standard, you should get
an error in its strict mode. For example, the compiler I use issues
the following messages:

mist 507 > KCC -c --strict t5.cc
"t5.cc", line 6: error: a reference of type "const int *&" (not
          const-qualified) cannot be initialized with a value of type "int *"
  const int*& refptrToConst = ptr; // should not be allowed!
                              ^

1 error detected in the compilation of "t5.cc".
KCC: Compilation failed.

Even in non-strict mode, it tells me that something is not quite right:

mist 508 > KCC -c  t.cpp
"t.cpp", line 6: warning: temporary used for initial value of reference to
          non-const (anachronism)
  const int*& refptrToConst = ptr; // should not be allowed!
                              ^

"t.cpp", line 6: warning: variable "ptr" is used before its value is set
  const int*& refptrToConst = ptr; // should not be allowed!
                              ^
--
#include <std/disclaimer.h>                 Kuck and Associates
David Nelson (david@kai.com)                1906 Fox Drive
http://www.kai.com/C_plus_plus/_index.html  Champaign, IL   61820
KAI C++ - Cross Platform C++ Compiler       (217) 356-2288 ext 36
---
[ 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: AllanW@my-dejanews.com
Date: 1998/06/17
Raw View
In article <6m5p8b$dp$1@mulga.cs.mu.OZ.AU>,
  fjh@cs.mu.OZ.AU (Fergus Henderson) wrote:
>
> zeisel@lnzx16.vai.co.at (Zeisel Helmut) writes:
> >Is there an "offical" statement to the lack of const correctness detected
> >by Thomas Becker: C++ Report May 1998 ?
>
> However, I think the problem is partly that the compilers
> which were tested were not invoked with appropriate options
> to enable standard conforming mode, and partly a misunderstanding.

Compiler options have nothing to do with it.  The non-conforming code compiles
without any warning.  On my system, executing it fails with an exception
caused when the program tries to modify memory in a read-only segment.

> >const int c = 42;
> >int* ptr;
> >
> >const int*& refptrToConst = ptr; // should not be allowed!
> >refptrToConst = &c;
> >*ptr = 43;  // changes c!
> >
> >In addition to Visual C++ and Borland 4.5.1 (tested by Becker),
> >the above example compiles without error or warning on VMS C++.
>
> The line marked "should not be allowed" is not valid C++.
> This assigns a temporary rvalue to a non-const reference,
> which is prohibited by the C++ standard.  A diagnostic is required.

That was Zeisel Helmut's point exactly.  Let's be clear about this:
    int main() {                 // 1
        const int ci=10;         // 2  Here is a constant
        int *ip;                 // 3  A pointer, points nowhere yet
        const int* * ipp = &ip;  // 4  Address of a const pointer
        *ipp = &ci;              // 5  Point to the const int
        ++*ip;                   // 6  Modify the const int
        std::cout << *ip << std::endl; // 7
    }
This gets an error on line 4.  We can fix it with a cast, of course.  If we
do, on some systems we die on line 6 (as the program tries to modify an
int in a read-only program section), on other systems we print 11 instead
of 10, and on still other systems some other unspecified behavior happens
(formats your hard disk?).
    int main() {                 // 1
        const int ci=10;         // 2  Here is a constant
        int *ip;                 // 3  A pointer, points nowhere yet
        const int* & ipr = &ip;  // 4  Reference to a const pointer
        ipr = &ci;               // 5  Point to the const int
        ++*ip;                   // 6  Modify the const int
        std::cout << *ip << std::endl; // 7
    }
I hope you recognize this as the same program, except it uses a reference to
const pointer instead of a pointer to const pointer.  The logic is the same,
and the result is the same (in my case, dying on line 6).  The only important
difference is that the C++ compiler didn't require a cast, didn't display
any error messages, didn't even display a warning message -- it just compiled
it as if it was completely legal.  (No, it's not legal.)

> Previous pre-ARM versions of C++ (pre-ARM, I think) did allow such
> assignments, and so for backwards compatibility, many compilers still
> support this, although most of them issue a warning by default.

Could be, but I'm surprised to hear it.  Do you know of a compiler (C or C++,
old or new) that ever (with any settings except "ignore errors, force compile
anyway") works this way with pointers instead of references? Why would this
ever work?

> Certainly if you enable standard conforming mode, then any conforming
> compiler will issue at least a warning, if not an error.
>
> However, even in the very old versions of C++ which allowed this,
> the reference was bound to a temporary -- the result of
> converting `ptr' from `int *' to `const int *'.  Thus
> the effect of the line `refptrToConst = &c;' was to modify
> this temporary, not to modify `ptr', and so the line
> marked "changes c!" would _not_ modify c.

Are you sure about this?  Initializing a reference to a pointer with an
l-value of pointer type shouldn't ever create a temporary, should it?  Either
it's compatible, in which case the reference works the obvious way, or it's
not, in which case the compiler spits out a warning (or else doesn't, if we
have a compiler bug).

If that could create a temporary, then I would be concerned that
    const int * &ptr2 = ptr;
could also create a temporary.  In fact, I'd start to worry about every use
of references throughout my program.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/   Now offering spam-free web-based newsreading


[ 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: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 1998/06/17
Raw View
Patrick Smith <patsmith@pobox.com> writes:

>Zeisel Helmut wrote:
>> In addition to Visual C++ and Borland 4.5.1 (tested by Becker),
>> the above example compiles without error or warning on VMS C++.
>First, egcs 1.0.1 (not the latest version, I know) also
>accepts this code.

If all these compilers accept that code even with strict conformance
options enabled, then they're all broken, I believe.

>Looking at the December 2, 1996 draft, I don't see how it
>permits this initialization.
...
>I haven't been keeping up with the development of the standard,
>and some of it is really hard to follow, but the above seems
>fairly clear to me.  Am I missing something obvious?

I don't think so.

--
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3        |     -- the last words of T. S. Garp.


[ 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              ]