Jump to content
  • Advertisement
Sign in to follow this  
  • entries
  • comments
  • views

Beware of your compiler!

Sign in to follow this  


One never really knows what the compiler is doing to your code...

Everyone may understand the basic underlay aspects of how the C and C++ compiler generates the assembly and machine code. Concepts such as pushing and popping the stack when calling routines, vtable, local stacks, memory addressing, etc.

However, your compiler may be still doing anything under the hood--without you ever knowing about it in anyway. Some of these are good, others are bad.

In this example is a problem that I have ran into today when developing my new kernel. As this is in a kernel envirement, The standard library and runtime are not being used. Instead, it is using its own.

I have written the following test routine after experiencing the problem in hopes to isolate it:

void SomeFunct (char* dest_ptr, int val, int count) {

for (; count!=0; count--)
*dest_ptr++ = (int)val;

Basic enough.

...Until the linker spit out an error:

1>Main.obj : error LNK2019: unresolved external symbol _memset referenced in function "void __stdcall SomeFunct(char *,int,int)" (?SomeFunct@@YGXPADHH@Z)

Notice what is happening here... _memset. Why would we get a linker error saying that our routine references memset()? After all, we have not called it anywhere within our routine (shown above.)

Lets disassemble everything here to see whats going on. This is what the compiler translated this source to...

?SomeFunct@@YGXPADHH@Z PROC ; SomeFunct, COMDAT

; 526 :
; 527 : for (; count!=0; count--)

00000 83 7c 24 0c 00 cmp DWORD PTR _count$[esp-4], 0
00005 74 14 je SHORT $LN3@SomeFunct
00007 ff 74 24 0c push DWORD PTR _count$[esp-4]
0000b ff 74 24 0c push DWORD PTR _val$[esp]
0000f ff 74 24 0c push DWORD PTR _dest_ptr$[esp+4]
00013 e8 00 00 00 00 call _memset &lt;<<< memset() call
00018 83 c4 0c add esp, 12 ; 0000000cH

; 528 : *dest_ptr++ = (int)val;
; 529 : }

0001b c2 0c 00 ret 12 ; 0000000cH
?SomeFunct@@YGXPADHH@Z ENDP ; SomeFunct

Notice the call to our memset() routine.

Keep in mind that we disabled the standard library. Because of this, _memset() is NOT defined, hence we get the linker error.

But wait -- Looking back at our code, notice we have not explicatly called memset() - the compiler implicitly did instead.


The moral of this story is to beware of what your compiler is doing--it may not be doing what you expect.
Sign in to follow this  


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!