3

I'm trying to define a function in a CPP file that is forward declared in the header file. I'd like to know the proper way to do it, since everything I've tried compiles and runs, and my analysis skills are not good enough to investigate if the functions are truly inlined.

Here's what I'd like to do

/// Source.h
void inlined_func(); // what specifiers should I put here?
                     // I was thinking about doing both `extern` and `__forceinline`



/// Source.cpp
__forceinline void inlined_func()
{
    std::cout << "we're in the inlined func" << std::endl;
}
  • There is no guarantee in the standard that declaring a function inline will result in inline code. However, you can declare, and define inline functions so long as there is only one definition per translation unit. They must also be the same if used in multiple translation units. Things like __forceinline are compiler specific extensions. – doug Sep 01 '18 at 05:04
  • Yes, @doug, that makes sense. As for compiler specific, that's why I have the MSVC++ tag. I'd like to specifically discuss the `__forceinline` qualifier –  Sep 01 '18 at 05:13
  • Also see: https://stackoverflow.com/questions/151919/when-should-i-use-forceinline-instead-of-inline – Will Bickford Sep 01 '18 at 05:46
  • Note that MSVC++ does not guarantee that __forceinline will, in fact, inline a function. see: https://msdn.microsoft.com/library/355f120c-2847-4608-ac04-8dda18ffe10c?f=255&MSPPError=-2147217396 – doug Sep 01 '18 at 06:03
  • What I'm using it for is proper usage of the `__forceinline` qualifier. I understand the lack of a guarantee, and I know the causes for it. I properly avoid it. That said, I still don't know if I should be using `extern` at all or how to properly identify that the definition is in the cpp file and not the header file. –  Sep 01 '18 at 06:10
  • 1
    Function declarations have external linkage by default. – molbdnilo Sep 01 '18 at 07:55

1 Answers1

2

A function declared as __forceinline by default gets internal linkage (the name can be referred to only in the current translation unit) as if declared as static. If you try to use it in another translation unit, you'll get a linker error LNK2001 unresolved external symbol .... To force external linkage, so that it can be referred to in other translation units, use extern keyword.

foo.h

void foo();

foo.cpp

#include <foo.h>
extern __forceinline void foo() {
    /*...*/
}

main.cpp

#include <foo.h>
int main() {
    foo();
}
Evg
  • 25,259
  • 5
  • 41
  • 83
  • 1
    Can MSVC still inline it though? – Niklas R Sep 01 '18 at 07:59
  • @NiklasR, yes. I deliberately checked it before writing an answer. – Evg Sep 01 '18 at 08:05
  • i'm currently using `extern __forceinline void foo();` in my header and `__forceinline void foo(){}` in my cpp file, and I'm getting no linkage error. is the inline specifier required in the header file? how can I check if the function is inlined? or do you know off the top of your head if this will inline properly? –  Sep 01 '18 at 19:55
  • @CryptographyMan You don't need `extern __forceinline` in the header. The simplest way to check if a function has been inlined is to look at the generated assembly code. Put a breakpoint somewhere before the function call and then check the *Disassembly* window. Don't forget to switch to the release mode. – Evg Sep 01 '18 at 20:00