8

I have a big class with lots of utility functions. those functions are very small and I would like them inlined.

The problem is they are all in a source file and should stay in the source file and not move to the header file (so I don't need to recompile everything every time one changes).

If I mark them as inline I get

symbols not found

Is there a way to make them inline or do I need to blindly trust the link time optimizer?
I need the code to be portable between clang 3 and gcc 4.6, but #defines based on compiler will be ok (so answer how to do it only in one of the compilers is fine too).

4
  • 5
    So, basically, you want magic. Commented Oct 24, 2011 at 23:21
  • @R.MartinhoFernandes: No, I want a linker that can copy-paste. Commented Oct 24, 2011 at 23:23
  • @Dani: Well, that's LTCG/LTO. Commented Oct 24, 2011 at 23:25
  • @Dani: Copy-paste is not the main purpose of inlining. Commented Oct 24, 2011 at 23:26

5 Answers 5

9

Place the implementation in an .inl file. Have only the necessary .cpp files #include it. This way changes to the implementation (touch .inl file) trigger recompile only of the dependent .cpp file. Changes to the definition (touch the .h file) trigger recompile of all files consuming the declaration.

This is a common practice for both inline functions and for template implementations. .inl files should be viewed basically as 'included cpp' files.

Sign up to request clarification or add additional context in comments.

1 Comment

This is not bad advice, but it doesn't help much with the compile-time costs. I suppose you could have one .inl file per function, but that would be more maintenance drag than it was worth, IMHO.
6

[These] functions are very small and I would like them inlined. [But] I don't [want] to recompile everything every time one changes.

You can't have both of these things. If a function is inlined, then you have no choice but to recompile all its callers when it changes. That's how inlining works. Even if you used a link-time optimizer to do it automatically at link time, you would still be paying the compilation-time cost of reprocessing all the callers.

AFAIK neither gcc 4.6 nor clang 3 have link-time optimizers that are up to scratch, by the way.

Editorial aside: No compiler that I know of has heuristics that are good enough to make manual inline annotations unnecessary, yet. Even VS2010, which I mentioned in the comments as an example of a link-time optimizer that is up to scratch, still needs quite a bit of advice about what to inline.

4 Comments

As the linker can modify symbol locations in a file, I'm pretty sure it can just paste a symbol in middle of another symbol if its instructed to.
@Dani: but that won't really speed up compilation much will it? It still needs to do the work on every caller, everytime those things change.
That wouldn't get you nearly the full benefit of inlining; inlining is done early in the compilation pipeline, so that subsequent phases can crush out unnecessary conditionals and rearrange code extensively between the caller and the callee. Also, I'm not aware of any linker that can do that. It would be very nearly as much work as a real link-time optimizer for less than 10% (I'd guesstimate) of the gain. Search for "linker relaxation" if you want to learn about the very limited set of optimizations that non-LTO linkers do; it tends to be things like subbing in shorter branch sequences.
GCC 4.6 does have an LTO that does work, in the sense that it won't crash or generate wrong code, but if you compare the output to, say, Visual Studio 2010 with profile feedback (this is, btw, the only compiler I know of with an LTO worth bothering to use) you'll see that it's got a long way to go yet.
5

If you want a function to be inline'd you have to place it in a header file, unless it's only being used in the same source file. The reason being that the compiler needs the actual function definition in order to place the definition "inline" wherever it's being called, and then compile it up.

You can find further information: here and here.

Comments

2

You need the function mandatory inlined - you place it in the class definition.

5 Comments

The -1 is because functions defined inside the class definition are not mandatory inline; they're exactly the same as if they were defined outside the class definition with the inline keyword. And you responded to a question about optimization with an answer about syntax, suggesting that you did not understand the question. (Your response shows that you do, but it wasn't clear from what you said.)
Zack, "because functions defined inside the class definition are not mandatory inline" - i guess it depends on the compiler, since I know at least one compiler where what I said is true.
@suddnely_me what compiler is that btw? What if I write a hundred line function in the class definition? Will it bloat my executable to the size of an 18-wheel truck?
Does that compiler, perhaps, also treat inline as mandatory rather than as a hint? Some compilers don't have any heuristics to tell them when to not inline something that the programmer thinks should be inlined.
@R. Martinho Fernandes: ICC, they say. I'm not pretty sure, but I'll be at work in a couple of hours and I can ask our developers.
1

One option could be to place the inline functions in a precompiled header file, which will speed up the compilation. But because of the nature of inlining functions all places they are used will have to be recompiled.

http://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html

5 Comments

If the functions are liable to change often, putting them in a PCH will probably slow down compilation even more.
@R.MartinhoFernandes I'd say it depends. I've seen very good results of both precompiling headers (a bunch common used) and doing parallel compilations. It sounds like speed is the issue here so these are my suggestions when using gnu tools.
The problem is that PCHs are for stuff that won't change often. The damn things take forever to recompile. That's my experience.
@R.MartinhoFernandes recompiling it is a one off thing...if it then is included many many times you get the payback. Big project, big gain, small project, small gain...(and one shouldn't have too much in it either, running stats and selecting files included >2 times was what we did)
Hmm, you're right. I guess that there is a certain threshold on the ratio between the number of users of the inlined functions and the frequency of changes to them where a PCH would pay off.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.