VC7.1 "__forceinline" not as good as VC6?

J

James Clark

We've been using VC6 for some time and are trying to port some specific
code to VC7.1 (VC++ .Net 2003). But I've come across problems where
__forceinline doesn't inline simple inline assembly that we need to be
inlined. VC6 has no such problems.

A simple, stripped-down, example is as follows:

__forceinline void func()
{
__asm
{
push offset _end
ret
_end:
}
}

It seems to be the "push offset _end" that's causing the problem. When
this is included, I get the following "warning C4714: function 'void
func ()' marked as __forceinline not inlined".

I've seen this in VC6 where certain mnemonics prevent inlining, and
changing these to use _emit fixes this, but I don't think _emit can be
used in the above example since the compiler needs to know the address
of "_end".

I've tried various compiler switches but nothing seems to be helping. My
only current solution is to build .libs in VC6 for the critical code and
use VC7 for the rest, but this isn't really a long-term solution.

Maybe there's a hidden option or #pragma somewhere to improve the
functionality of __forceinline?

Any ideas?
 
G

Guest

JC [Mon, 05 Apr 2004 14:01:38 +0100]:
changing these to use _emit fixes this, but I don't think _emit can be
used in the above example since the compiler needs to know the address
of "_end".

I don't think the x86 gives direct access to the pc (program
counter, whatever it's called in x86) so those of us that
did this sort of stuff used a trick like this:

call me
me: pop eax ; eax->$

and pop it from the stack. Bound to mess up the call/return
stack (as far as internal CPU optimization goes) but if you
know better go for it. Of course you'd have to add a few
bytes to get to the location you wanted (_end), but that
should work.
 
J

James Clark

I don't think the x86 gives direct access to the pc (program
counter, whatever it's called in x86) so those of us that
did this sort of stuff used a trick like this:

call me
me: pop eax ; eax->$

and pop it from the stack. Bound to mess up the call/return
stack (as far as internal CPU optimization goes) but if you
know better go for it. Of course you'd have to add a few
bytes to get to the location you wanted (_end), but that
should work.

You are correct, you can't access EIP (instruction pointer) directly in x86.

I am aware of the trick you suggest, but had used "push offset label" in
preference to avoid manual calculations of the offsets. But when using
this idea, my simple test code does now inline OK. I have lots of more
complex code to modify and test but hopefully this can be done an
everything will inline.

Still doesn't explain why VC.Net doesn't do this as well as VC6, maybe
it thinks it knows better?

Many thanks for the idea.
 

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

Top