Re: Is overriding a function of a library in accordance with C++ standard?
Lighter wrote:
Is overriding a function of a library in accordance with C++
standard?
No. Except in a few, very limited cases, it is undefined
behavior.
The following code is passed by the VS 2005 and Dev C++.
#include <cstdlib>
#include <iostream>
using namespace std;
size_t strlen(const char* p)
{
return 0;
} // !!! Note this !!! The standard library function strlen is
deliberately overriden.
int main(int argc, char *argv[])
{
system("PAUSE");
return EXIT_SUCCESS;
}
There is even no warning after compiling the code.
There are several open questions here. First, it is unclear
whether the compiler actually sees the declaration for the
system strlen. The standard says it is present in <cstring>
(and <string.h>). This header may be included by one of the two
headers you include, or it may not be; we don't know.
Second is the fact that it is unspecified whether the system
strlen has "C" language linkage, or "C++". If it has "C++"
linkage, your strlen in global namespace is an unrelated
function, and has nothing to do with the function in the
standard library. If it has "C" linkage, I'm not sure; I think
it is still a different function, but I think the text in ?7.5/6
could be interpreted either way. (Had you defined `size_t
std::strlen( char const* )', or `extern "C" size_t strlen( char
const* )' there would be no question---you are providing the
definition of the library function, which is undefined
behavior. In this case, however, there is nothing, neither
`extern "C"', nor `std::', to tell the compiler that this is the
same function as the one defined `extern "C"' in std::.)
Finally, almost no implementation is fully conformant, in that
almost all insert the names of the functions in the <c...>
headers in global namespace, even though the standard says they
shouldn't. If your compilers have done this, then once again,
your strlen is the definition for the standard function, and you
have undefined behavior.
In front of the fact, I have to make a guess that all the C++
compilers are conformed to the following rules:
1) The compiler first compiles all the source file included in the
project into object files;
The compiler compiles the files you give it as source files into
object files, yes. In this case, the object file will contain
definitions for the symbols main (something---how the compiler
defines main is a bit special, and it normally cannot follow the
usual mangling rules), and either `::strlen(char const*)',
mangled as it would any normal C++ function, or `extern "C"
(std):: strlen(char const*)', mangled as a C function.
2) At link time, the compiler first searches the object files
for all the unresolved symbols; if it fails to find some
symbols, then the compiler will search the libraries which are
included in the project to find the symbols.
More or less. Unix compiler drivers normally process the files
in the order you give them---if you specify a library before an
object file, unresolved externals in that object file will not
be resolved from the library. (I think that Windows linkers do
process all object files first, then all libraries,
reiteratively until either no more object files are pulled in,
or all externals are resolved.)
3) If the object files containes a symbol, then the symbols
that have the same name in the libraries will be ignored.
Again, more or less. Typically, a library consists of object
files, each of which becomes part of your program if (and only
if) it resolves an unresolved external. Once an object file
from the library becomes part of your program, however, all of
the external symbols in it are taken into account.
In the case of independant functions, like strlen, the normal
procedure in a well written library is for each function to be
in a separate source file, thus to generate a separate object
file in the library. In the case of closely related functions
which must work together (e.g. malloc/free), both functions
would usually be in the same object file, so that if you replace
one, you have to replace the other, or get an error (multiple
definitions for the same symbol) at link time (and of course,
you should never have a program which uses malloc, but not
free). Similarly, virtual class member functions can all go
into the same object file, because once you have an instance of
the class, they are all referenced.
In your case, you don't use strlen, so it isn't an unresolved
external (except in the unlikely case that system uses it). If
some other module had used it, what happens would depend on
whether your function ended up with the same (mangled) name as
the one in the system library or not. With the same name, all
uses of tye system library function would in fact call yours
(which would probably cause more than a few things to not work).
If the compiler didn't consider yours as an implementation of
the system function, however, there would be no conflict, and
everything would work as expected.
--
James Kanze GABI Software
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]