On Friday, 8 February 2013 at 09:33:19 UTC, Jonathan M Davis wrote:
On Friday, February 08, 2013 09:30:41 Artur Skawina wrote:
On 02/08/13 01:33, Jonathan M Davis wrote:
> Hmmm. I wouldn't have thought that you could get the > function pointer at > compiler time. Regardless, you lose any possibility of > inlining the > function call, which is the main problem AFAIK, though I > don't know if
> they would have been an option in the case of dup anyway.

It doesn't affect inlining. (Obviously, that's compiler dependent, but
there's no reason why it should and indeed does not w/ gdc)

How could it not affect inlining? You're using a pointer to a function instead of the function itself, so it can't be inlined. Do you mean that dup in particular doens't get inlined even when called directly? That's quite possible, but in the general case, using a function pointer rather than calling a function directly risks taking a small efficiency hit due to the fact
that the function can no longer be inlined.

- Jonathan M Davis

Well, aren't you saying that because usually, function pointers aren't obtained at compile time?

In any case, I also tested it, and the disassemble seems to give the exact same code (inlined, as far as I can tell) for calling via function or function pointer:
http://d.godbolt.org/#{%22version%22%3A3%2C%22filterAsm%22%3A{%22labels%22%3Atrue%2C%22directives%22%3Atrue%2C%22commentOnly%22%3Atrue}%2C%22compilers%22%3A[{%22source%22%3A%22%2F%2F%20Type%20your%20code%20here%2C%20or%20load%20an%20example.\n\nint%20i%3B\n\nvoid%20foo%28%29\n{\n%20%20%2B%2Bi%3B\n}\n\nvoid%20bar%28%29\n{\n%20%20enum%20fun%20%3D%20cast%28void%20function%28%29%20nothrow%29%20%26foo%3B\n%20%20fun%28%29%3B\n%20%20%2F%2Ffoo%28%29%3B\n}\n\nvoid%20main%28%29\n{\n%20%20bar%28%29%3B\n%20%20assert%28i%20%3D%3D%201%29%3B\n}%22%2C%22compiler%22%3A%22%2Fusr%2Fbin%2Fgdc%22%2C%22options%22%3A%22-O2%20-march%3Dnative%20-inline%22}]}

http://d.godbolt.org/#{%22version%22%3A3%2C%22filterAsm%22%3A{%22labels%22%3Atrue%2C%22directives%22%3Atrue%2C%22commentOnly%22%3Atrue}%2C%22compilers%22%3A[{%22source%22%3A%22%2F%2F%20Type%20your%20code%20here%2C%20or%20load%20an%20example.\n\nint%20i%3B\n\nvoid%20foo%28%29\n{\n%20%20%2B%2Bi%3B\n}\n\nvoid%20bar%28%29\n{\n%20%20%2F%2Fenum%20fun%20%3D%20cast%28void%20function%28%29%20nothrow%29%20%26foo%3B\n%20%20%2F%2Ffun%28%29%3B\n%20%20foo%28%29%3B\n}\n\nvoid%20main%28%29\n{\n%20%20bar%28%29%3B\n%20%20assert%28i%20%3D%3D%201%29%3B\n}%22%2C%22compiler%22%3A%22%2Fusr%2Fbin%2Fgdc%22%2C%22options%22%3A%22-O2%20-march%3Dnative%20-inline%22}]}

And a third version, after adding the "nothrow" keyword. Slight changes, but I can't tell if they are "true" changes:
http://d.godbolt.org/#{%22version%22%3A3%2C%22filterAsm%22%3A{%22labels%22%3Atrue%2C%22directives%22%3Atrue%2C%22commentOnly%22%3Atrue}%2C%22compilers%22%3A[{%22source%22%3A%22%2F%2F%20Type%20your%20code%20here%2C%20or%20load%20an%20example.\n\nint%20i%3B\n\nvoid%20foo%28%29\n{\n%20%20%2B%2Bi%3B\n}\n\nvoid%20bar%28%29%20nothrow\n{\n%20%20enum%20fun%20%3D%20cast%28void%20function%28%29%20nothrow%29%20%26foo%3B\n%20%20fun%28%29%3B\n%20%20%2F%2Ffoo%28%29%3B\n}\n\nvoid%20main%28%29\n{\n%20%20bar%28%29%3B\n%20%20assert%28i%20%3D%3D%201%29%3B\n}%22%2C%22compiler%22%3A%22%2Fusr%2Fbin%2Fgdc%22%2C%22options%22%3A%22-O2%20-march%3Dnative%20-inline%22}]}

That said, when everything is said and done, the try catch version also generates the same inline code
http://d.godbolt.org/#{%22version%22%3A3%2C%22filterAsm%22%3A{%22labels%22%3Atrue%2C%22directives%22%3Atrue%2C%22commentOnly%22%3Atrue}%2C%22compilers%22%3A[{%22source%22%3A%22%2F%2F%20Type%20your%20code%20here%2C%20or%20load%20an%20example.\n\nint%20i%3B\n\nvoid%20foo%28%29\n{\n%20%20%2B%2Bi%3B\n}\n\nvoid%20bar%28%29%20nothrow\n{\n%20%20enum%20fun%20%3D%20cast%28void%20function%28%29%20nothrow%29%20%26foo%3B\n%20%20fun%28%29%3B\n%20%20%2F%2Ffoo%28%29%3B\n}\n\nvoid%20main%28%29\n{\n%20%20bar%28%29%3B\n%20%20assert%28i%20%3D%3D%201%29%3B\n}%22%2C%22compiler%22%3A%22%2Fusr%2Fbin%2Fgdc%22%2C%22options%22%3A%22-O2%20-march%3Dnative%20-inline%22}]}

But in this case, the compiler has access to the call, so it can *tell* exceptions won't get thrown.

Finally, in this last version, which calls dup, we can see the "cast" version takes less intructions that the try/catch version.

http://d.godbolt.org/#{%22version%22%3A3%2C%22filterAsm%22%3A{%22labels%22%3Atrue%2C%22directives%22%3Atrue%2C%22commentOnly%22%3Atrue}%2C%22compilers%22%3A[{%22source%22%3A%22%2F%2F%20Type%20your%20code%20here%2C%20or%20load%20an%20example.\n\nchar[]%20s%3B\n\nvoid%20foo%28%29\n{\n%20%20s%20%3D%20\%22hello\%22.dup%3B\n}\n\nversion%28all%29\n{\n%20%20void%20bar%28%29%20nothrow\n%20%20{\n%20%20%20%20enum%20fun%20%3D%20cast%28void%20function%28%29%20nothrow%29%20%26foo%3B\n%20%20%20%20fun%28%29%3B\n%20%20}\n}\nelse\n{\n%20%20void%20bar%28%29%20nothrow\n%20%20{\n%20%20%20%20try{\n%20%20%20%20%20%20foo%28%29%3B\n%20%20%20%20}catch{}\n%20%20}\n}\n\nvoid%20main%28%29\n{\n%20%20bar%28%29%3B\n%20%20assert%28s%20%3D%3D%20\%22hello\%22%29%3B\n}%22%2C%22compiler%22%3A%22%2Fusr%2Fbin%2Fgdc%22%2C%22options%22%3A%22-O2%20-march%3Dnative%20-inline%22}]}

But at the end of the day, it is a dangerous semantic for not that much gain.

Reply via email to