Now I analyse some old code, which was not written by me. In headers there are many declarations like this:
SVPDSDKDLLEXPORT inline C3vec mult(C3vec src, D3DXMATRIX &m);
SVPDSDKDLLEXPORT is defined as _declspec(dllexport), if it is used in SVPDSDK; as _declspec(dllimport), if it is used in any project, which uses SVPDSDK.dll. Inlining here seems very strange for me as there is no definition in the header, it is in .cpp file, but compilation and linkage of SVPDSDK and all projects, which use respective DLL, are executed without any problems. I assume, that it is just ignored and the function is exported as though is was not inlined.
I've found this discussion: C++ : inline functions with dllimport/dllexport?
Looked like I should have removed "inline" from all such declarations, don't mix inlining and export/import. But then I found this topic in MSDN: http://msdn.microsoft.com/en-us/library/xa0d9ste
I don't understand some parts of it.
You can define as inline a function with the dllexport attribute. In this case, the function is always instantiated and exported, whether or not any module in the program references the function. The function is presumed to be imported by another program.
Firstly, "the function is always instantiated", what does it mean? I've found only topics about template functions instantiation in C++, no any other instantiation. Is it connected only with templates or not?
Secondly, "the function is always exported". I don't understand it at all. Is it possible, that function with declspec(_dllexport) is not exported in some cases? In what cases?
Now about import:
You can also define as inline a function declared with the dllimport attribute. In this case, the function can be expanded (subject to /Ob specifications), but never instantiated. In particular, if the address of an inline imported function is taken, the address of the function residing in the DLL is returned. This behavior is the same as taking the address of a non-inline imported function.
Again, I don't understand, what means instantiation in this case.
While writing this question and analysing topic from MSDN, I made a conclusion, that function, which is exported/imported and inlined at the same time, is inlined only in its project itself (SVPDSDK in my case) and is non-inlined in all importing projects. It's not evidently declared in MSDN topic. If I don't import it in any project, which uses it, and I have not a definition in its header file, it will be an ordinary inlined function, so I will get a linkage error. Then it seems for me that it's agreeable to mix inlining and export/import, thought it contradicts an answer in the stackoverflow discussion, mentioned above. Am I right?
And I still don't understand all this words about inlined functions instantiation.
I'm sorry, that I combined some questions in one topic, but I don't know, how to divide it in separate ones, because they are united by the same issue and the same materials. However, I would be grateful, if anyone could clarify this questions for me.
In fact, inline
is a sort of hint for the optimizer. Compiler can still generate a real function with body, pushing args on the stack, etc. This will not break any logic. It would definitely do so if your "inline" function would have more than 10000 lines of code. Microsoft even has special __forceinline
keyword. Guess why it was introduced.
The function is always instantiated and exported ...
The wording might be not perfect here. Instantiation means here that a body and an entry point will be generated. This has nothing to do with template instantiation. The whole paragraph means that __declspec
is more important than inline
.
For dllimport
they basically write that dllimport
prevents generation of body of this inline function in the current binary module, while the inline expansion is still possible.