Re: Requiring client code to provide implementation file.
On Jan 7, 7:55 am, Carlos Moreno <cm_n...@mailinator.com> wrote:
Following a discussion a while ago on the subject of "Automatic
Serialization", one of the aspects that came up was the need to
include in the programs some timestamp, so that if the program
is recompiled (indicating that the layout of the data for the class
may have changed), at run-time this can be known.
So, my framework provides a base class representing the application,
which is intended for users of the framework to derive from:
---- File application.h ----
class Application
{
public:
Application ()
: d_compile_timestamp ( __DATE__ __TIME__ )
{}
// ...
};
The Application class declaration above appears to violate C++'s "one
definition rule" (ODR) - specifically ?3.2/5. The first bullet in that
paragraph requires that the definition of a class must - in each
translation unit in which the definition appears - consist of the same
sequence of tokens.
Yet the tokens that the preprocessor uses to replace __DATE__ and
__TIME__ do not remain constant from one translation unit to the next.
In fact,.because the date and time macros change so frequently, there
is effecitvely no way to ensure that Application's d_compile_timestamp
has a constant value initializer - let alone that d_compile_timestamp
will have the same a value in both a derived and its base class.
In short, using time stamps to track revisions to a class definition
is simply not a workable solution. Instead of relying on a continually-
changing time stamp value, the program really needs to find a value
that changes only upon each revision of the class header file itself.
Fortunately, there is at least one place where such a value can
usually be found: the source code control system (SCCS) that manages
the program's source code files. (And if, for some reason, the
program's soruce files are not under SCCS control, then the first step
is to check in those source files into an SCCS)
Most of the popular SCCS systems widely used today, including cvs,
subversion and perforce - can recognize something called "RCS
keywords" - special tokens placed in source files as stand-in for
values that the SCCS furnishes. So whenever the SCCS encounters one of
these RCS keywords in a file, the SCCS replaces the keyword with the
value that the keyword represents. (In this case, the RCS keyword of
interest is $Revision$, that is, the revision number of the header
file itself).
For example, an Application class definition that uses RCS keyword to
specify the value of the class version number, could look something
like this:
class Application
{
public:
Application ()
: d_class_version ( $Revision$ )
{}
// ...
};
Now, whenever a client checks out the "application.h" header file, the
SCCS will replace the $Revision$ keyword with the actual revision
number of Application.h itself. Furthermore, since the class version
number remains unchanged between class revisions, there is no need to
ban inline constructors in user-code (a requirement that was as
unenforceable as it was unreasonable in the first place.)
Naturally, the specific details of this proposed solution are likely
to vary somewhat - depending on the particular SCCS system in use. So,
it likely will be necessary to consult the relevant SCCS documentation
and to find which RCS keywords are recognized and what additional
steps (if any) must be taken RCS keywords to be recognized.
Greg
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]