Share via


I like FORCEINLINE

For kernel mode code, if I have choice between using a #define or a FORCEINLINE function, the FORCEINLINE function wins every time.  #defines have their place, especially for quotifying (the # operator) or concatenating (the ## operator), but they have no place in my heart for constants or pseudo functions.

FORCEINLINEs have type checking.  On a debug build, they show up in the symbol information.  They do not have weird side affects due to replacement by expression (such as invoking the #define max(a++, b++) would have).  In KMDF, we use FORCEINLINE functions for all DDI calls and all of our structure init functions. The type checking alone is enough for me; it allows for more maintainable and correct code.

I am also intentionally leaving templates out of this for a reason.  C++ is not supported in the kernel.  For those who use C++, you are cautioned to use a safe subset of it.  Templates are far from a safe subset because there is no way to deterministically control into which section the code will be linked into.  This is important because you can accidentally have your template generated code placed into a PAGEable section, but the code cannot be PAGEable (and you BSOD very quickly :( ).

Comments

  • Anonymous
    February 17, 2006
    It seems to me that it would be (a) relatively easy (b) extremely useful if the compiler team made the required updates to the compiler to control the location of all generated code.  C++ is a much better language than C for writing code that must be reliable.  Even if you don't use any other C++ constructs, the pair of stricter typechecking and RAII make it worthwhile.

  • Anonymous
    February 17, 2006
    Using C++ strictly as a better C is in terms of typechecking is supported.  I would say that using a contructor/desctructor pattern for RAII is also supported because in this case you must explicitly create both functions; the danger lies in the compiler autogenerating the code for you and then that code getting placed in a random spot by the linker.  I have used this pattern in a driver before safely.

    The compiler team did make alot changes based on our feedback in the latest Visual Studio release.  But the changes by themselves are not enough, they need to be verified, validated, and regresssion tested before we can tell folks to use them.  That takes time and right now we are trying to get a product (Vista, i think a few folks have heard about it ;) ) out the door and this is not a Vista feature, but it will see the light of day in the future.
  • Anonymous
    February 17, 2006
    The comment has been removed
  • Anonymous
    February 17, 2006
    The comment has been removed
  • Anonymous
    February 17, 2006
    The comment has been removed
  • Anonymous
    February 17, 2006
    I really don't like FORCEINLINE simply because it in reality doesn't forceinline :( I disocvered this the hard way while in (C++) trying to create a type safe _alloca wrapper.

    Sadly enough since forceinline really doesn't force inline the call headaches really did ensue. So it's really that much better than __inline or the traditional C++ const/inline constructs.
  • Anonymous
    February 18, 2006
    DrunkCod: FORCEINLINE is not an absolute. From talking to the compiler team, it is a much stronger suggestion to inline then __inline is, but still not an absolute.   On a debug build, it is never honored.  For a retail build, there are situation/usages when inlining will not occur.  For instance, if the candidate function has an SEH block or C++ exception handling, the inlining will not occur.  Also, if there are varargs, inline will also not occur.  There are other limitations as well, I don't remember them all offhand.

    In your case of wrapping _alloca, I can totally see why the compiler would not let you do this.  _alloca grows the stack for the allocation, so by the time your inline funciton returned, the _alloca memory is gone.  In this case a #define might be better.
  • Anonymous
    February 19, 2006
    The comment has been removed
  • Anonymous
    February 19, 2006
    The comment has been removed
  • Anonymous
    February 19, 2006
    Nice to see someone is doing some kernel blogging.  I wish I had time to keep writing for my blog, but that has not been in the cards for a long time now.
  • Anonymous
    February 22, 2006
    doron,
    This might be a stupid question but can you explain why the DDI function pointers are stored in a jump table. What does this indirection provide.
  • Anonymous
    February 22, 2006
    The comment has been removed
  • Anonymous
    March 27, 2006
    I think that the C preprocessor is a very powerful tool, but I like to limit
    my use of #defines.  I...
  • Anonymous
    June 08, 2009
    PingBack from http://insomniacuresite.info/story.php?id=2162