Topic: Question about file-scope constants...


Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1996/03/12
Raw View
David Held <dheld@turing.cs.stcloud.msus.edu> writes:

>I was under the impression that a const object of any type and its data
>members remained constant throughout their scope (which should be the
>whole file, in this case), and that those data members were correctly
>accessible from within any function in that scope.

That's true, provided your program does not do anything which might
constitute "undefined behaviour", such as dereferencing an
uninitialized pointer.  However, from your description of the symptoms,
it sounds like your program is invoking undefined behaviour at some
point, in which case all bets are off.

The C++ standard allows implementations to detect such errors at
run-time, but it does not require them to do so.  Compilers are not
required to place const objects in read-only memory, so if your program
assigns via a stray pointer, your const objects could be overwriten.
(Practically speaking, I would suggest that you get hold of an
implementation which does perform run-time checking.  They're very
useful for debugging problems like this.)

>class Exception
>{
[...]
>public:
>  Exception(char *);
[...]
>};
[...]
>const Exception Memory_Error("Memory Error");

Incidentally, tying in with another thread in comp.std.c++,
it is the frequency of code like the above which means that
changing the type of string literals from `char []' to `const char []'
would break lots of code.  I consider such code to be bad style --
the constructor for exception should take `const char *', not `char *' --
but until all compilers warn about it, such code will remain frequent,
even in newly developed C++-style code that makes full use of new features
such as exceptions, templates, namespaces, etc.

>Here's my problem: I declare several const Exceptions in the exception.h
>file, since they are ones that I expect to use in every program
>(Memory_Error, Boundary_Error, File_Error, etc.).

Note that in C++, declaring a global variable `const' also has the side
effect of giving that variable default internal linkage, just as if it was
declared `static'.  If you want a const to have external linkage, you
need to explicitly declare it `extern'.

>I wrote a demo program where the main body is in a file called
>main.cpp, and the exception testing demo is in exception_demo.cpp.  I
>have appropriate header files for both, and I include exception.h in
>both (I set a meta-variable to make sure exception.h only gets included
>once).  Exception_demo.cpp contains the testing function, but apparently
>when the program enters this only function of exception_demo.cpp, one of
>the exceptions declared in exception.h gets mysteriously modified.

This effect which you observed in the debugger may be due to a different copy
of the exception coming into scope when you enter a function in a different
translation unit.  As noted above, global consts default to internal linkage,
so you will get one copy of each global const for every translation unit.

>There is no conceivable way that my code could be modifying the object data.

Famous last words ;-)

In C and C++, there are hundreds of conceivable ways for code to have
undefined behaviour.

--
Fergus Henderson              WWW: http://www.cs.mu.oz.au/~fjh
fjh@cs.mu.oz.au               PGP: finger fjh@128.250.37.3
---
[ 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
]