Skip to main content
GameDev.net gamedev.net
🔒 Locked

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

Started by cqulyx Aug 25, 2006 at 1:13 AM 18 replies 3.3k views
Original Post
cqulyx
cqulyx
Is overriding a function of a library in accordance with C++ standard? The following code is passed by the VS 2005 and Dev C++. #include #include 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[]) { int n = strlen("Hello"); // n equals 0 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. [Edited by - cqulyx on August 25, 2006 1:59:07 AM]
God said: "Let there be light!" and there was light.
skulldrudgery
skulldrudgery
If you didn't include , then the compiler doesn't know anything about strlen().

Edit:
Nevermind, I was barking up the wrong tree. And apparently you DON'T have to include for strlen.

Edit2:
I think you don't run into any compilation errors because you never try to use the function.
skulldrudgery--A tricky bit of toil
rpreller
rpreller
It's not in accordance with good programming or software engineering practices at least. If you're going to do something like that, have a wrapper class or library.
cqulyx
cqulyx
Quote:
Original post by skulldrudgery
If you didn't include , then the compiler doesn't know anything about strlen().


I'm sure that what you said is incorrect. If you comment the function definition of strlen provided by the user, you can see that the compiler calls the default version of the function.

Quote:
Original post by skulldrudgery
Edit:
Nevermind, I was barking up the wrong tree. And apparently you DON'T have to include for strlen.


This is unrelated to inclusion.

Quote:
Original post by skulldrudgery
Edit2:
I think you don't run into any compilation errors because you never try to use the function.


Even if I use strlen("Hello"); in main() body, the compiler still doesn't give me any complaint.

God said: "Let there be light!" and there was light.
Shimon Shvartsbroit
Shimon Shvartsbroit
It's actually amusing.. Seems like a compiler bug to me.. I have tried compiling the bellow program with visual studio 2005 and got 1 error during first try of compilation.. But when tried compiling the same program a second time it passed with 0 warnings and 0 errors.

I don't know if there's anything special with standard libraries. I have always treaten them as ordinary additional libraries. To my current knowledge they should obey the ODR (One Definition Rule). Meaning that a non-static function can defined only once per program.

For my best knowledge it's uncommon practice to override standard functions. Personally I would probably curse the programmer who would override standard functions and caused a bug on the way. Hunting such bugs can be very time concuming, especially when you expect something to work because it was made by the experts and was tested by huge amount of programmers(people that use standard libraries). Other than that, I advise you to stop working with C functions and move on to CPP, such as std::string class. Even though it's bit bloated, it has more advantages over C functions.


#include <cstring>size_t  strlen(const char *){  return 0;}void main(){  strlen("123");}  Compiling...1.cppLinking...1.obj : error LNK2005: _strlen already defined in MSVCRTD.lib(MSVCR80D.dll)D:\CPP Projects\gd\Debug\gd.exe : fatal error LNK1169: one or more multiply defined symbols foundBuild log was saved at "file://d:\CPP Projects\gd\Debug\BuildLog.htm"gd - 2 error(s), 0 warning(s)========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========





HTH,
Shimon

"If you're stuck, ask for help. If you keep running up against the same wall, take a break and see if you can find a different wall."
Kest
Kest
Quote:
Original post by Anonymous Poster
anyways! it's really not a good idea, because if anyone else uses it, they would assume that they're calling the library function and not the overloaded one.

In some cases it wouldn't matter as much. Such as if you just wanted to deal with null pointers as though they are empty strings in functions like strcmp(). I'm pretty sure most of the standard string functions throw an error or access violation.

But I still agree that a wrapper would be better.
Aardvajk
Aardvajk
I'm a bit confused here - surely if you include with a properly standards-compliant C++ compiler, the library strlen would be in the std namespace so you would be free to declare another strlen in the global or your own namespace without a conflict?

Or does this not apply if it is included via ?
Nitage
Nitage
Regardless of what the C++ standard says, the microsoft C standard libaries headers for C++ headers(, etc) place their contents into both the global namespace AND namepsace std. I believe they simply include the old style .h file then issue a number of using directives in the std namespace.

I don't have my copy of the standard available at work, so I don't know if that's correct.

EDIT: That's for the 2003 version. The draft version of the standard on the internet indicates that this behaviour is incorrect.
Aardvajk
Aardvajk
Surprisingly, that would seem to be true for VS 2005 as well. The following code compiles and runs from the VS 2005 IDE:

#include <cstdio>int main(int,const char **av){	printf("hello\n");	std::printf("hello\n");}


I can only guess this is an extension (hopefully that can somehow be disabled) for compatibility with legacy code, but then surely any legacy code that was pre namespace std would include ?

I notice that requires std::string s="hello"; and fails on string s="hello";, so it is inconsistent to say the least.

Even Borland's BCC55 implements and correctly and that has been available free for a number of years.
Conner McCloud
Conner McCloud
Quote:
Original post by EasilyConfused
I notice that requires std::string s="hello"; and fails on string s="hello";, so it is inconsistent to say the least.

std::string is not part of the C Standard Library, so there is no inconsistancy.

CM
Aardvajk
Aardvajk
Following the standard for everything would be consistent. Following the standard for nothing would be consistent. Following the standard for the C++ SL and not the C SL is, IMHO, inconsistent, hence my comment.

I am aware that std::string is not part of the C standard library.
keen
keen
In g++ it gives 0, in gcc this gives 5, which is weird aswell.
Check out this for the output.
ZQJ
ZQJ
I think I can probably explain GCC's behaviour: the strlen() routine is in libc not libstdc++, i.e. it is exported as a C function. Your version when compiled with C++ will have a different name because it will be mangled to include the return type and parameter types, so it appears to be a different function to the linker.

Other than that - I'm not quite sure why the C version behaves as it does on GCC. You can overload library functions, but it's usually done from a library for debugging purposes (e.g. Electric Fence), and I think that depends on the order in which libraries are loaded to work. In any case I think this is pretty conclusively nonportable. Even if a compiler implented the standard correctly (as I understand it), so that strlen was only in the std namespace your code would not work because your strlen is not in the standard namespace, and I'm pretty sure the C++ standard prohibits putting your own functions into the standard namespace.
Bregma
Bregma
Yes, it is compliant to be able to supply a function with any name you choose, as long as it is not a reserved word.

If a compler barfs when you supply your own definition for strlen(), that compiler is either non-compliant or you have not found the switch to disable that behaviour (such as -fno-builtins or its equivalent).

It is necessary to be able to supply a definition for a standard function so that you can use alternate implementations of libraries for whatever reason. Even the basic libraries that come supplied with your compiler are just regular libraries.

The standard does not talk about linkage or dictate implementation.

If you supply your own definition of, say, strlen(), it should compile just fine. The linker will pick it up and use it, and not try to resolve the symbol further by searching any additional libraries. Your definition will replace the one from the standard library. No magic, that's the way seprate compilation is intended to work.

In terms of C++, if you attempt to replace a name in the std:: namespace you will not have written a fully compliant program, but that's more a sort of "you break it, you're on your own" kinda thing. I've spent a lot of time replacing such functions as a part of implementing libstdc++, so I know the compiler isn't going to stop you. You just really need to know the internals of that particular version of the library and compiler to be safe.
Stephen M. Webb
Professional Free Software Developer

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.