Is overriding a function of a library in accordance with C++ standard?

L

Lighter

Is overriding a function of a library in accordance with C++ standard?

The following code are 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. 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;

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.

3) If the object files containes a symbol, then the symbols that have
the same name in the libraries will be ignored.

Am I correct?

Any help will be appreciated. Many thanks in advance.
 
B

benben

Lighter said:
Is overriding a function of a library in accordance with C++ standard?

You can't override an existing function because that is violation to the
One Definition Rule (ODR.)

More explanation below.
The following code are 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. 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;

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.

3) If the object files containes a symbol, then the symbols that have
the same name in the libraries will be ignored.

Am I correct?

Nope. The standard library strlen resides in the std namespace. The
using directive merely makes such a name available in the global scope.
Your own version of strlen is declared in the global scope and so hides
the std::strlen.

To truly override strlen and get a compiler error you can do the following:

#include <cstring>

namespace std{
size_t strlen(const char*){return 0;}
}

int main()
{
strlen("oops!");
}
Any help will be appreciated. Many thanks in advance.

Regards,
Ben
 
F

Fred Zwarts

Lighter said:
Is overriding a function of a library in accordance with C++ standard?

The following code are 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. 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;

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.

3) If the object files containes a symbol, then the symbols that have
the same name in the libraries will be ignored.

Am I correct?

I am not sure what the standard says about it. In practice this works except
if other functions in the run-time library are used in the program.
On many platforms, the run-time functions are pre-linked.
(Linux uses shared object files (.so) .
Windows uses dynamic linked libraries (.dll)
VMS uses shareable images (.exe))
In such cases the standard version of the function is present in the pre-linked
file and will be used internally.
In order to use your own version of the function, special link options must
be use to prevent the use of the pre-linked run-time library. This will make
the resulting executable file much larger, as it now contains all run-time
library functions used by the program. In addition these functions are no
longer shared with other programs, so that the program may use more memory.
 
L

Lighter

benben said:
Nope. The standard library strlen resides in the std namespace. The
using directive merely makes such a name available in the global scope.
Your own version of strlen is declared in the global scope and so hides
the std::strlen.

To truly override strlen and get a compiler error you can do the following:

#include <cstring>

namespace std{
size_t strlen(const char*){return 0;}
}

int main()
{
strlen("oops!");
}

Dev C++ can still normally compile the code, but VS 2005 report an
error.
 
N

neo

I am using vs2k5. Your code is working perfectly; in your code I
include iostream.h in your code, its give error as following:

e:\vc\bug\bug\bug.cpp(12) : error C2883: 'std::strlen' : function
declaration conflicts with 'strlen' introduced by using-declaration
c:\program files\microsoft visual studio
8\vc\include\string.h(80) : see declaration of 'strlen'

If I want to use iostream.h, how we would be override strlen function?

In my understanding strlen function will not be override because it
will be conflict between two functions in std namespace, if it is
possible to override std function, I am interested to learn it.

Regards,
-aims

Lighter said:
Is overriding a function of a library in accordance with C++ standard?

You can't override an existing function because that is violation to the
One Definition Rule (ODR.)

More explanation below.
The following code are 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. 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;

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.

3) If the object files containes a symbol, then the symbols that have
the same name in the libraries will be ignored.

Am I correct?

Nope. The standard library strlen resides in the std namespace. The
using directive merely makes such a name available in the global scope.
Your own version of strlen is declared in the global scope and so hides
the std::strlen.

To truly override strlen and get a compiler error you can do the following:

#include <cstring>

namespace std{
size_t strlen(const char*){return 0;}
}

int main()
{
strlen("oops!");
}
Any help will be appreciated. Many thanks in advance.

Regards,
Ben
 
M

Michiel.Salters

neo said:
I am using vs2k5. Your code is working perfectly; in your code I
include iostream.h in your code, its give error

That's to be expected; its <iostream.h> is not a standard C++ header
but a microsoft-specific one to help their customers deal with
pre-standard
C++ code. Any error you get with it has nothing to do with standard
C++, the topic here. Try the microsoft.* newsgroups.

HTH,
Michiel Salters
 
J

Jerry Coffin

Is overriding a function of a library in accordance with C++ standard?

Sometimes. Just for example, you are specifically allowed to supply your
own memory management functions. There are rather tight restrictions on
what you can add to namespace std though.
#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.

Only sort of. The standard library has a function named "std::strlen".
If you include <cstring> that's how it's visible. If you include
<string.h>, it's been made visible in the global namespace (as if by
"using std::strlen"), but its name is still "std::strlen", not
"::strlen".

As such, what we have are two different functions with two different
names, but a mechanism (or two, technically -- the using declaration and
the using directive) that allows us to ignore that particular difference
in the name.

That means your name doesn't directly collide with the one in the
standard library. You're not allowed to do this though:

namespace std {
size_t strlen(const char *p) {
return 0;
}
};

Now, one other minor detail: in C++, any standard header is allowed to
include any other standard header. That means that even though you
haven't included either <cstring> or <string.h>, it's possible that
having included <iostream> and <cstdlib> could include <cstring> or
<string.h>. In that case, the name in your code would collide with the
name from the standard library, and the compiler would reject your code.

Most of the rest of your summary about how compilation works is
generally correct in general, but not required -- and while most
compilers work about as you described, there are a few that work
substantially differently (e.g. the last time I looked at it, IBM VA C++
took a somewhat more global approach to things. I never tested it with
code like yours but I wouldn't be surprised if it reacted somewhat
differently to your code).

To summarize: the compiler is allowed but not required to reject your
code. As an aside, I'd also add that C has substantially stricter rules
in this respect than C++. In C all names starting with 'str' are
reserved, so code like your's would have undefined behavior.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,019
Latest member
RoxannaSta

Latest Threads

Top