Inlining with /EHsc

I found that compiler (VC++ 2005 Pro) not inlining some functions/operators when using /EHsc flag and you have an empty destructor in class.

class vector3
{
public:
 
  vector3();
  vector3(const vector3& vec);
  vector3(float x, float y, float z);
  ~vector3() {} // if remove this compiler will inline operator+.

  // some code
};

inline vector3 operator+(const vector3& a, const vector3& b)
{
  return vector3(a.x + b.x, a.y + b.y, a.z + b.z);
}

Can somebody explain this behavior



Answer this question

Inlining with /EHsc

  • Wendy_B

    Jonathan Caves - MSFT wrote:
    As exceptions are involved the optimizer has decided that it is too expensive to inline the function - i.e. it feels it can generate better code if it leaves it as a function. Are your compiling for size (/O1) or speed (/O2)

    I am compiling for speed (/O2).

    I think my first post insufficiently describes the problem (or my English is very bad. :) ). Optimizer behavior that I describe depends on presence of an empty destructor in class. If you have it optimizer will not inline some functions/operators, if you remove the destructor optimizer will inline them. In both cases I use /EHsc.


  • JoraPJL

    Did the change make it through regression testing


  • MarijnStevens

    As exceptions are involved the optimizer has decided that it is too expensive to inline the function - i.e. it feels it can generate better code if it leaves it as a function. Are your compiling for size (/O1) or speed (/O2)

  • Scotty Sparks

    I looked at this again, and I still cannot give you anything definitive. Here's my best guess.

    operator+ is creating a temporary object. Suppose during or after the temporary object were created, an exception was thrown. Since your object has a destructor, it would be called to during unwind. Perhaps this is preventing inlining.

    I tried using __declspec(nothrow) on all three vector functions (ctor, dtor, and operator+), and that doesn't help. One of the compiler engineers would have to figure this one out. If this is by design due to corner case scenarios, I would hope that they can make refinements so the compiler is smarter. Your example is showing a significant performance degradation, especially on constant vectors.

    I'll create a bug report on your behalf and post back the link.


  • dalterio

    Actually ... this landed on my desk this morning. It looks as if the restriction may no longer apply (the code in question is really, really old). We are in the process of removing the restriction and running all our tests. Fingers-crossed nothing will break and we can check this in.

  • raq

    Here is the link: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx FeedbackID=211600 You can bookmark this to follow its status. If you want to add comments, you can.


  • jhknys

    Followup: this bug report was marked by design due to a more general issue involving destructors and exception handling.
  • Marken

    Also, the inlinee must be visible during compilation at the call site in order for it to be inlined. This typically means that you should put them in header files. If your inlinee is sitting in another obj file, then it won't get inlined unless you're using "Whole Program Optimization," aka Link-Time Code Generation. This is the /GL compile flag, and the /LTCG linker flag, and they can enabled via the project properties. Note that LTCG doesn't always give you an appreciable win, so profile before and after to decide if it is worth the extended build time.
  • Inlining with /EHsc