Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Why is inline function "not working" (like I expected)?

87 views
Skip to first unread message

JiiPee

unread,
Jan 12, 2017, 12:23:00 PM1/12/17
to
I though inline function is placed in the place of calling and without
creating the temporary function parameters. But seems like inline
always(?) creates the function parameters?

I tested like this:

class Foo
{
public:
Foo* x;
void setX(Foo val) {
x = new Foo;
*x = val;
}
};

int main() {

Foo a, b;

a.setX(b);

}

When I debug this I can see that the temporary function argument "Foo
val" is created and b assigned into it. And after that is does the copy
operation "*x = val;" as well. I was hoping inlining would pass the
creation of "val" but it does not. Is this always the case that the
function parameters are always created when calllling an inline function?

I was hoping the compiler to generate a code something like (after
placing inline code into main()):

Foo a, b;

Foo::x = new Foo;
*Foo::x = b;

... so it would have passed the copy-contruction call which is kind of
needless here. Why the compiler does not do that? How about if I have
"int" parameters, will it also create those temporary function parameters?

Scott Lurndal

unread,
Jan 12, 2017, 12:44:43 PM1/12/17
to
JiiPee <n...@notvalid.com> writes:
>I though inline function is placed in the place of calling and without
>creating the temporary function parameters. But seems like inline
>always(?) creates the function parameters?
>

Did you compile it with a sufficient level of optimization?

gcc won't optimize those out unless you specify -O2 or -O3.

JiiPee

unread,
Jan 12, 2017, 12:49:28 PM1/12/17
to
Well this is Visual Studio 2015, with default setting. I compiled a
release version. I need to change its settings? I though its set to
optimize..?

JiiPee

unread,
Jan 12, 2017, 12:55:24 PM1/12/17
to
On 12/01/2017 17:49, Stefan Ram wrote:
> but I'd
> say the »inline substitution« of f(int x){g(x);} into f(2)
> is {int x=2;g(x);}.


oh, so the inline does not take off that x-variable. hmm, in most of my
inline needs I would prefer:

{g(2);} as a result... because I looop millions times per second an array in a loop, so that temporary would slow down that loop.

inline void set(int index, int value) {
myValues[index] = value;
}

I would need this to be made:
set(2, 866) ->
myValues[2] = 866;

red floyd

unread,
Jan 12, 2017, 1:18:34 PM1/12/17
to
Pass by const ref?

void Foo::setX(const Foo& val) {
// ...
}

JiiPee

unread,
Jan 12, 2017, 1:25:44 PM1/12/17
to
yes in this case. But how would you use array indexes without need to
copy indexes? I know we can get a reference to the array, but if we want
to use an index:


Foo a;

a.set(i); // ---> set an array value with index i.


Juha Nieminen

unread,
Jan 16, 2017, 2:12:17 AM1/16/17
to
JiiPee <n...@notvalid.com> wrote:
> I though inline function is placed in the place of calling and without
> creating the temporary function parameters.

The 'inline' keyword has absolutely nothing to do with optimization.
It's an instruction for the linker (telling it that if it finds that
same function in more than one object file, to use only one of them
and discard the rest).

Some compilers *might* use it as a hint for optimization, but that's
just some extra that can't be relied upon. Some compilers might ignore
it completely (other than for that linker thing).

Wouter van Ooijen

unread,
Jan 16, 2017, 2:31:23 AM1/16/17
to
Op 16-Jan-17 om 08:12 schreef Juha Nieminen:
> JiiPee <n...@notvalid.com> wrote:
>> I though inline function is placed in the place of calling and without
>> creating the temporary function parameters.
>
> The 'inline' keyword has absolutely nothing to do with optimization.
> It's an instruction for the linker (telling it that if it finds that
> same function in more than one object file, to use only one of them
> and discard the rest).

Where did you get this idea?

Wouter "Objects? No Thanks!" van Ooijen

JiiPee

unread,
Jan 16, 2017, 2:33:28 AM1/16/17
to
ok, but if think about it... lets say we have an inline funtion:

inline int getSum(int a, int b) {

return a + b;

}


and we call it:

int x=9, y=8, ret;

ret = getSum(x, y);

...

for me it does not make any sense for the compiler NOT to do this like:

ret = {x + y}; // (*)

rather than first creating those two temprorarys a and b and then copy
x,y into and this way give the sum. What is a good reason here (as the
function is so super small) for a compiler NOT to do like in (*)? I see
absolutely no reason for creating those temporaries here especially as
the function is so tiny. Somebody give me a good argument please why its
better here to create the temporaries (and waste time)?

Ian Collins

unread,
Jan 16, 2017, 3:20:37 AM1/16/17
to
Because it is just a hint. Its only practical use is for functions
defined in headers.

--
Ian

Jeff-Relf.Me

unread,
Jan 16, 2017, 10:12:20 AM1/16/17
to
JiiPee, Juha Nieminen, Wouter and then Ian Collins wrote:
> > > > I though inline function is placed in the place of calling and without
> > > > creating the temporary function parameters.
> > >
> > > The 'inline' keyword has absolutely nothing to do with optimization.
> > > It's an instruction for the linker (telling it that if it finds that
> > > same function in more than one object file, to use only one of them
> > > and discard the rest).
> >
> > Where did you get this idea?
> 
> Because it is just a hint.  
> It's only practical use is for functions defined in headers.

Not true.  "inline" works properly for me, Visual C++ 2015.
I've set the appropriate compiler options, of course.

I know it works because I can't set a break point there,
on an inline function.  See:
https://msdn.microsoft.com/en-us/library/cx3b23a3.aspx

Bo Persson

unread,
Jan 16, 2017, 11:28:13 AM1/16/17
to
No, optimizing the code that way seems like a good idea.

The thing is that the compiler likely does all that, whether you add
inline to the function or not.

The inline keyword is needed if you have the function in a header, but
not if it is local to a .cpp file.



Bo Persson

Wouter van Ooijen

unread,
Jan 16, 2017, 11:37:29 AM1/16/17
to
Op 16-Jan-17 om 16:12 schreef Jeff-Relf.Me:
The fact that your setup does inline the functions marked as such
doesn't prove that the inline keyword is no more than a hint.

Wouter "Objects? No thanks!" van Ooijen

Wouter van Ooijen

unread,
Jan 16, 2017, 11:38:14 AM1/16/17
to
Op 16-Jan-17 om 09:20 schreef Ian Collins:
That it is "just a hint" is 100% correct, but that doesn't have anything
to do with the linker.

Jeff-Relf.Me

unread,
Jan 16, 2017, 2:32:47 PM1/16/17
to
You ( Wouter ) replied ( to me and Ian Collins ):
> > > Because it is just a hint.
> > > It's only practical use is for functions defined in headers.
> >
> > Not true.  "inline" works properly for me, Visual C++ 2015.
> > I've set the appropriate compiler options, of course.
> >
> > I know it works because I can't set a break point there,
> > on an inline function.  See:
> > https://msdn.microsoft.com/en-us/library/cx3b23a3.aspx
> 
> The fact that your setup does inline the functions marked as such 
> doesn't prove that the inline keyword is no more than a hint.

I know when it works, and I don't create .h files;
according to Ian, that means I'd have _no use for "inline".

Mr Flibble

unread,
Jan 16, 2017, 2:40:23 PM1/16/17
to
If you never create header files then you are not a serious/professional
C or C++ programmer and have certainly never created anything other than
trivial toy; you are instead a fucktarded annoying cunt and,
more than likely, a troll.

/Flibble

Ian Collins

unread,
Jan 16, 2017, 2:42:44 PM1/16/17
to
"*Microsoft Specific*

The __inline keyword tells the compiler..."

You do have a bit of a problem with underscores, don't you?
--
Ian

Ian Collins

unread,
Jan 16, 2017, 2:43:46 PM1/16/17
to
The compiler would inline the code without the hint.

--
Ian

JiiPee

unread,
Jan 16, 2017, 2:45:50 PM1/16/17
to
On 16/01/2017 16:27, Bo Persson wrote:
> The thing is that the compiler likely does all that, whether you add
> inline to the function or not.


But I tested this (with an object instead of int x;) and it did make a
temporary variable and initialize it with the calling object (so it
called copy constructor to it).

JiiPee

unread,
Jan 16, 2017, 2:48:42 PM1/16/17
to
On 16/01/2017 16:27, Bo Persson wrote:
> The thing is that the compiler likely does all that, whether you add
> inline to the function or not.


You can test it yourself. Instead of

int x, y;

make your own class and pass its object. Then check if it goes into its
copy contructor.


void get(MyObject obj)

{

MyObject a;

a = obj;

//.. and do something with a.

}


Jeff-Relf.Me

unread,
Jan 16, 2017, 2:48:46 PM1/16/17
to
You ( Leigh Johnston ) told me:
> If you never create header files then you are not a serious/professional
> C or C++ programmer and have certainly never created anything other than
> trivial toy

It has works for me, for 35 years now, coding for my living.
I consolidate everything into one file, so I don't need a .h file.

My C++ Coding Rules:  http://Jeff-Relf.Me/C++CodingRules.HTM

Mr Flibble

unread,
Jan 16, 2017, 2:54:28 PM1/16/17
to
On 16/01/2017 19:48, Jeff-Relf.Me wrote:
> You ( Leigh Johnston ) told me:
>> If you never create header files then you are not a serious/professional
>> C or C++ programmer and have certainly never created anything other than
>> trivial toy
>
> It has works for me, for 35 years now, coding for my living.
> I consolidate everything into one file, so I don't need a .h file.

I would not hire you as you appear to be clueless. I feel sorry for
anyone who has to maintain the crap that you output and I feel sorry for
your clients who have paid you money for the software they mistakenly
rely on.

/Flibble

Jeff-Relf.Me

unread,
Jan 16, 2017, 3:00:54 PM1/16/17
to
You ( Ian Collins ) replied ( to me ):
> The compiler would inline the code without the hint.

No, incorrect.
In the Visual C++ code, below, I can _not break on "ER()";
yet, once I remove the "inline", I can.

inline   int ER(    int X,    int Y ) { return X > Y ? X : Y ;  } 

int j = 3, k = 6, y ;

y = ER( j, k );

Jeff-Relf.Me

unread,
Jan 16, 2017, 3:04:56 PM1/16/17
to
You ( Leigh Johnston ) told me:
> I feel sorry for anyone who has to maintain the crap 
> that you output and I feel sorry for your clients who 
> have paid you money for the software they mistakenly rely on.

I've been programming for "The Bankers" ( ABA.COM )
for the last 24 years... they haven't fired me yet.
You ?

If "maintenance" is your primary concern... 

  You should be riding in a little red wagon, not a Ferrari.

Your little red wagon.

My Ferrari.

Mr Flibble

unread,
Jan 16, 2017, 4:06:13 PM1/16/17
to
On 16/01/2017 20:04, Jeff-Relf.Me wrote:
> You ( Leigh Johnston ) told me:
>> I feel sorry for anyone who has to maintain the crap
>> that you output and I feel sorry for your clients who
>> have paid you money for the software they mistakenly rely on.
>
> I've been programming for "The Bankers" ( ABA.COM )
> for the last 24 years... they haven't fired me yet.
> You ?
>
> If "maintenance" is your primary concern...

Writing maintainable code is one of my concerns yes: the fact that it
isn't one of yours tells us all we need to know about your professionalism.

If I had to maintain your code I would do so by throwing all your code
away and starting again: your output has no value whatsoever.

[snip]

/Flibble

woodb...@gmail.com

unread,
Jan 16, 2017, 5:31:00 PM1/16/17
to
On Monday, January 16, 2017 at 1:40:23 PM UTC-6, Mr Flibble wrote:

Please don't swear here.

Maybe he creates .hh and .hpp files.

Brian
Ebenezer Enterprises - In G-d we trust.
http://webEbenezer.net

Mr Flibble

unread,
Jan 16, 2017, 6:00:41 PM1/16/17
to
On 16/01/2017 22:30, woodb...@gmail.com wrote:
> On Monday, January 16, 2017 at 1:40:23 PM UTC-6, Mr Flibble wrote:
>
> Please don't swear here.
>
> Maybe he creates .hh and .hpp files.

Brian, please shut the fuck up.

/Flibble

Jeff-Relf.Me

unread,
Jan 16, 2017, 11:23:26 PM1/16/17
to
You ( Leigh Johnston ) replied ( to me ):
> > I've been programming for "The Bankers" ( ABA.COM )
> > for the last 24 years... they haven't fired me yet.
> > You ?
> >
> > If "maintenance" is your primary concern...
> >   You should be riding in a little red wagon, not a Ferrari.
> 
> If I had to maintain your code I would do so by throwing all your code 
> away and starting again: your output has no value whatsoever.

Cool, I do the same.
I'm famous for tossing code, I do it all the time.

I'm _not worried about getting fired, You ?

The best code ( for me, and only me ) 
is the code I designed and wrote myself.
As a programmer, text file comparison is essential, like water;
so I wrote my own diff routines ScreenShot.  Help/Settings: X.HTM.

Jeff-Relf.Me

unread,
Jan 16, 2017, 11:32:08 PM1/16/17
to
You ( Brian Wood ) replied ( to Leigh Johnston ):
> Please don't swear here.

It's compliment, I don't mind.

In this _PlayGround ( not workspace ):

  Guys speak the "Insult Dialect";
  where "Fuck You" is just a "Hello".

  Women speak the "Praise Dialect";
  where "I Love You" is just a "Hello".

> Maybe he creates .hh and .hpp files.

No, I don't create _any include files.

I don't even know what a .hh file is,
nor do I care to find out.  

Ian Collins

unread,
Jan 17, 2017, 3:00:50 AM1/17/17
to
You won't if you enable optimisation.

--
Ian

Ian Collins

unread,
Jan 17, 2017, 3:03:23 AM1/17/17
to
On 01/17/17 11:30 AM, woodb...@gmail.com wrote:
> On Monday, January 16, 2017 at 1:40:23 PM UTC-6, Mr Flibble wrote:
>
> Please don't swear here.

If you have nothing constructive to add, please Foxtrot Oscar and annoy
another group.

--
Ian

woodb...@gmail.com

unread,
Jan 17, 2017, 1:28:33 PM1/17/17
to
Developing and hosting the C++ Middleware Writer (CMW) as a free
service is my main contribution. And I'm willing to make a
contribution to someone who is interested in using the CMW.
There's more info here:

http://webEbenezer.net/about.html


Brian
Ebenezer Enterprises - Enjoy programming again.
http://webEbenezer.net

Bo Persson

unread,
Jan 17, 2017, 1:37:48 PM1/17/17
to
The question was about

int getSum(int a, int b) {

return a + b;

}

which any sensible compiler will inline as a + b, unless you explicitly
ask it NOT to inline any functions.


You can find a good example of what an optimizing compiler really does,
if you look here:

http://stackoverflow.com/a/11639305/597607

Note that there are no "inline"s in that code.



Bo Persson

red floyd

unread,
Jan 17, 2017, 2:51:23 PM1/17/17
to
On 1/17/2017 10:28 AM, woodb...@gmail.com wrote:

> Developing and hosting the C++ Middleware Writer (CMW) as a free
> service is my main contribution.

So basically, your contribution to this group is shilling
your own software, and bitching about everyone else's choice
of words.

Fuck off.


JiiPee

unread,
Jan 17, 2017, 2:53:14 PM1/17/17
to
On 17/01/2017 18:37, Bo Persson wrote:
> int getSum(int a, int b) {
>
> return a + b;
>
> }
>
> which any sensible compiler will inline as a + b


yes but are you sure? I have this kind of thing in my real code where I
want to have an inline function with index parameters to arrays index.
But a bit worried if it creates temporaries. But I guess I have to
measure time how long it takes to be sure.

Scott Lurndal

unread,
Jan 17, 2017, 3:26:01 PM1/17/17
to
Or you could simply look at the generated machine code.

JiiPee

unread,
Jan 17, 2017, 4:29:31 PM1/17/17
to
yes true. but have not done that really before.

Vir Campestris

unread,
Jan 17, 2017, 4:50:13 PM1/17/17
to
On 17/01/2017 21:29, JiiPee wrote:
> yes true. but have not done that really before.

About time you did.

(I'm working on a MIPS CPU at the moment, and I've never used one
before. I couldn't _write_ MIPS assembler the way I could half a dozen
others, but I can read it. Even the branch delay slots...)

Andy

woodb...@gmail.com

unread,
Jan 17, 2017, 8:58:40 PM1/17/17
to
On Tuesday, January 17, 2017 at 1:51:23 PM UTC-6, red floyd wrote:
> On 1/17/2017 10:28 AM, woodb...@gmail.com wrote:
>
> > Developing and hosting the C++ Middleware Writer (CMW) as a free
> > service is my main contribution.
>
> So basically, your contribution to this group is shilling
> your own software,

I have thousands of lines of high quality open source
code here:

https://github.com/Ebenezer-group/onwards

G-d has used many people from this newsgroup and other
forums to help me develop the software.

I think I have one of the best programming languages and
architectures for developing an on line code generator.
As I see it, my code generator is another feather in C++'s
cap. Do Go, D or Rust have on line code generators?


> and bitching about everyone else's choice
> of words.
>

I nag those who swear here. Think of it as a
virtual clean room.



Brian
Ebenezer Enterprises
http://webEbenezer.net

Juha Nieminen

unread,
Jan 18, 2017, 2:16:54 AM1/18/17
to
Wouter van Ooijen <wou...@voti.nl> wrote:
>> Because it is just a hint. Its only practical use is for functions
>> defined in headers.
>
> That it is "just a hint" is 100% correct, but that doesn't have anything
> to do with the linker.

It has everything to do with the linker. Why do you think that you have
to specify the 'inline' keyword if you ever implement a function in a
header file that gets included in more than one source file?

As for actually inlining, the compiler is completely free to ignore
that keyword completely and have it play no part in its optimization
decisions.

Juha Nieminen

unread,
Jan 18, 2017, 2:22:08 AM1/18/17
to
JiiPee <n...@notvalid.com> wrote:
> for me it does not make any sense for the compiler NOT to do this like:
>
> ret = {x + y}; // (*)

If the compiler sees the function's implementation from the place where
it's being called, it will probably inline it, but not because you wrote
the keyword 'inline'. (And, in fact, some modern compilers will even try
to inline functions across compilation units during linking.)

The compiler is free to inline the function even if there is no 'inline'
keyword. The compiler is free to *not* inline the function even if the
keyword is there.

Where 'inline' does make a tangible difference (and must do so because
the standard mandates it) is when the same function implementation appears
in more than one compilation unit (which most typically happens when the
implementation is in a header file that gets included in more than one
source file). Without the 'inline' keyword you would get a linker error
for multiple symbols; with the keyword the linker will just use one
of them and discard the rest.

JiiPee

unread,
Jan 18, 2017, 2:41:09 AM1/18/17
to
On 18/01/2017 07:22, Juha Nieminen wrote:
> The compiler is free to*not* inline the function even if the
> keyword is there.


and free to use the argument temporaries as well.

But if I have a loop where I run some function 10 millions times this
might become significant whether it inlines or not. And does the
compiler understand this? Does it take account that I am running that
inline code in such a loop? But it surely cannot always know what is the
size of the loop. This is why I think it would be better to have a "pure
inline" keyword which ALWAYS inlines. Because otherwise I have to go and
check the assemply code to see what happened.... or time it. So that
takes more development time to do that. Well, other option I have is to
make a reference based function instead, but it just looks uglier.

Values get() {

return values;

}


this does not make any overhead but calling it looks a bit ugly:

vals.get()[5];

instead of:

vals.get(5);

David Brown

unread,
Jan 18, 2017, 3:26:54 AM1/18/17
to
On 18/01/17 02:58, woodb...@gmail.com wrote:
> On Tuesday, January 17, 2017 at 1:51:23 PM UTC-6, red floyd wrote:
>> On 1/17/2017 10:28 AM, woodb...@gmail.com wrote:
>>
>> > Developing and hosting the C++ Middleware Writer (CMW) as a free
>> > service is my main contribution.
>>
>> So basically, your contribution to this group is shilling
>> your own software,
>
> I have thousands of lines of high quality open source
> code here:
>
> https://github.com/Ebenezer-group/onwards
>
> G-d has used many people from this newsgroup and other
> forums to help me develop the software.

No, he has not - at least not from this newsgroup. I can't answer for
"other forums".

If /you/ have had help and learned more about C++ from this newsgroup,
then that's great. Helping each other and teaching each other is one of
the main purposes of the group.

But speaking for myself, if I give someone in a newsgroup some useful
ideas or tips, it is to help the /people/ in the group. It is /not/ to
help people's software or their projects. Do you understand the
difference?

Personally, I think your software has little use and I think your "this
is all about God" attitude drives away any developers or users who might
be interested - I certainly would not waste my time helping with the
development. But I am quite happy to respect that /you/ feel your
project is important and useful, and I am quite happy to help /you/ if I
had C++ tips or ideas to give you. Do you understand the difference here?

And /God/ has not "used" me, or anyone else here. /You/ are free to
think he has - but you are /not/ free to attribute all the help you have
received from /people/ to your invisible friend. If someone helps me, I
thank /them/ - I don't thank the bogeyman.


>
> I think I have one of the best programming languages and
> architectures for developing an on line code generator.
> As I see it, my code generator is another feather in C++'s
> cap. Do Go, D or Rust have on line code generators?

Until you have established a community and support around your software,
it is nothing more than a small personal project. And you will never
establish such a community until you drop the narcissism and
megalomania. You are /not/ God's prophet and later-day Noah sent to
save the world from Java by bringing back his people to the true C++
way. You are someone who has an idea for a C++ application that you
feel is important, and you are having a hard time selling that idea to
others. When you understand that, and begin to think about what it will
take to get a community around your idea, then you can make progress.
And here is a free tip for you /and/ your project - drop every hint of
religion, politics, nationalism, sexism and other bigotry from your
website, your project and your posts. (Honestly - I write this for your
own good, and the benefit of your project, not to attack you or your
beliefs. It is also for the good of this newsgroup - I would much
rather see you write posts based on your C++ knowledge and experience,
than more nonsense about how your "middleware writer" is the best idea
since sliced bread and will save the world.)

>
>
>> and bitching about everyone else's choice
>> of words.
>>
>
> I nag those who swear here. Think of it as a
> virtual clean room.

This is not a "virtual clean room". Other people don't think so - why
do /you/ think you have the right to impose bizarre rules on the
language people use here?

If someone were using seriously bad language, then it would be fine to
make an occasional post asking them to stop. Knee-jerk reactions and
auto-responder posts are never helpful.



David Brown

unread,
Jan 18, 2017, 3:32:33 AM1/18/17
to
It is definitely worth getting familiar with viewing generated assembly.
You won't want to do it for everything - in particular, you will want
to stick to small test functions. It can quickly get overwhelming for
larger bits of code. The details are going to be beyond you for a
while, but you can get some ideas pretty quickly, such as whether a
function is inlined or not.

Probably the most convenient way to do this is with the online compiler
at <https://gcc.godbolt.org/#>. It also lets you test out a wide
variety of compilers. I recommend using "-O1" switch when you are
viewing the assembly - too low optimisation makes it hard to follow the
code because everything goes on the stack, and too high makes it hard to
follow the re-organisation of the code structure.

Ian Collins

unread,
Jan 18, 2017, 3:34:55 AM1/18/17
to
On 01/18/17 02:58 PM, woodb...@gmail.com wrote:
> On Tuesday, January 17, 2017 at 1:51:23 PM UTC-6, red floyd wrote:
>> On 1/17/2017 10:28 AM, woodb...@gmail.com wrote:
>>
>> > Developing and hosting the C++ Middleware Writer (CMW) as a free
>> > service is my main contribution.
>>
>> So basically, your contribution to this group is shilling
>> your own software,
>
> I have thousands of lines of high quality open source
> code here:
>
> https://github.com/Ebenezer-group/onwards
>
> G-d has used many people from this newsgroup and other
> forums to help me develop the software.

If you believe in a deity, at least learn how to spell it.

>> and bitching about everyone else's choice
>> of words.
>>
>
> I nag those who swear here. Think of it as a
> virtual clean room.

A virtual clean room where you can insult whole countries with impunity?
yeah, right.

--
Ian

JiiPee

unread,
Jan 18, 2017, 3:38:58 AM1/18/17
to
sure, thanks will check that

JiiPee

unread,
Jan 18, 2017, 3:50:41 AM1/18/17
to
On 18/01/2017 08:32, David Brown wrote:
>
> Probably the most convenient way to do this is with the online compiler
> at <https://gcc.godbolt.org/#>. It also lets you test out a wide
> variety of compilers. I recommend using "-O1" switch when you are
> viewing the assembly - too low optimisation makes it hard to follow the
> code because everything goes on the stack, and too high makes it hard to
> follow the re-organisation of the code structure.
>

When I do this (-O1):

inline int square(int num) {
return num * num;
}

int foo(int q) {
int a = square(q);
return a * 2;
}


it only gives :

foo(int):
imul edi, edi
lea eax, [rdi+rdi]
ret


looks like the square() disappears? Where is it? because if I do without
inline I get the same foo:

square(int):
imul edi, edi
mov eax, edi
ret
foo(int):
imul edi, edi
lea eax, [rdi+rdi]
ret

Melzzzzz

unread,
Jan 18, 2017, 3:54:55 AM1/18/17
to
On Wed, 18 Jan 2017 21:34:45 +1300
Ian Collins <ian-...@hotmail.com> wrote:

> On 01/18/17 02:58 PM, woodb...@gmail.com wrote:
> > On Tuesday, January 17, 2017 at 1:51:23 PM UTC-6, red floyd wrote:
> >> On 1/17/2017 10:28 AM, woodb...@gmail.com wrote:
> >>
> >> > Developing and hosting the C++ Middleware Writer (CMW) as a
> >> > free service is my main contribution.
> >>
> >> So basically, your contribution to this group is shilling
> >> your own software,
> >
> > I have thousands of lines of high quality open source
> > code here:
> >
> > https://github.com/Ebenezer-group/onwards
> >
> > G-d has used many people from this newsgroup and other
> > forums to help me develop the software.
>
> If you believe in a deity, at least learn how to spell it.

Just imagine how huge your ego must be when you believe that creator of
universe is personally interested in you ;)




--
press any key to continue or any other to quit...

Robert Wessel

unread,
Jan 18, 2017, 3:55:13 AM1/18/17
to
There's nothing in the standard that *requires* any particular code
generation by the compiler. That being said, some compilers have a
"stronger" hint than the standard "inline", MSVCs "__forceinline", for
example. And even that has exceptions (for example, MSVC will not
normally inline recursive functions, or ones that are called
virtually, or if a pointer to the function is made) - so it's still
just a hint, albeit a strong one.

In gcc, "__attribute__((always_inline))" will do something similar.

But most compilers use some heuristics to decide what to inline. Often
(usually) an inline (either explicit, or the implicit one with an
inline member function) impacts that assessment. Things like number
of uses, size of the function, whether or not it's called in a loop,
are all things likely to be taken into account. Often other ways to
influence the mechanism exist (often command line parameters or
#pragmas).

Robert Wessel

unread,
Jan 18, 2017, 3:59:55 AM1/18/17
to
The compiler is free to inline anything it likes. In this case, it's
a very short function, and the actual inlined code is shorter than an
actual call to the out-of-line function. Win all around.

JiiPee

unread,
Jan 18, 2017, 4:17:57 AM1/18/17
to
On 18/01/2017 09:00, Robert Wessel wrote:
> foo(int):
> imul edi, edi
> lea eax, [rdi+rdi]
> ret


oh I see this

imul edi, edi

is doing the square. So in inline and non-inline versions the foo() is the same.

JiiPee

unread,
Jan 18, 2017, 4:28:55 AM1/18/17
to
On 18/01/2017 08:32, David Brown wrote:
> Probably the most convenient way to do this is with the online compiler
> at<https://gcc.godbolt.org/#>.


I tried my proglem:

class A
{
public:
int a[20];
inline int get(int num) {
return a[num];
}
};

int foo(int q) {
A a;
return a.a[1] * 2;
}

...

and then with:

int foo(int q) {
A a;
return a.get(1) * 2;
}


and they gave the same assembly, so I guess my fear for using index
function parameter so that it would create a temporary is not really
what happens. Seems like it does not create that temporary num-index.

Robert Wessel

unread,
Jan 18, 2017, 4:40:16 AM1/18/17
to
Yes.

This appears to be x86-64 Unix code. The calling convention for that
ABI would pass the first (integer) parameter in rdi (since this is
only a 32 bit parameter, only edi, the low half of rdi, is used). It's
multiplied by itself (the imul instruction), then rax, the return
register for that ABI, (again, the low half of that, eax, is actually
used for the 32 bit value being returned) is loaded with twice the
value in rdi (the lea* adds edi to itself and stores the result in
eax). The code then returns to the caller.

Since you omitted the inline in the second example, the compiler was
obligated to create the actual callable square() function, since it
might get used from elsewhere. It *could* have called square() from
foo() in that case (and it might if you set the optimization level to
"debug"), but as I mentioned, in this case the inlined code is
actually shorter than the call instruction it would have had to
generate, so it inlined it anyway.

In many cases the descision is much more complex. Consider an
function tagged "inline". If it's only called *once*, it's probably
worth inlining in any case. If it's called more than once, if it's
more than a small function, it may excessively increase code size from
multiple copies being inlined. That increases cache pressure and
negatively impacts performance. OTOH, even a large function may see
substantial performance gains from inlining if it can be significantly
specialized based on the actual parameters. Consider:

int foo(int a)
{
blah0;
if (a==1) {blah1; blah2; blah3;}
else if (a==2) {blah4; blah5; blah6;}
else {blah7; blah8; blah9;}
blah10;
}

A call of "foo(2)" can be inlined as simply:

{blah0; blah4; blah5; blah6; blah10;}

with out the (now) dead code in the other two conditional legs, or any
of the actual conditional branches.

While the removal of the call overhead is important, the main
advantage inlining provides is the ability to specialize the function
to the point of call.


*lea is "load effective address", and it's frequently (ab)used to do
simple arithmetic.

David Brown

unread,
Jan 18, 2017, 6:30:23 AM1/18/17
to
On 18/01/17 10:40, Robert Wessel wrote:
> On Wed, 18 Jan 2017 09:17:42 +0000, JiiPee <n...@notvalid.com> wrote:
>
>> On 18/01/2017 09:00, Robert Wessel wrote:
>>> foo(int):
>>> imul edi, edi
>>> lea eax, [rdi+rdi]
>>> ret
>>
>>
>> oh I see this
>>
>> imul edi, edi
>>
>> is doing the square. So in inline and non-inline versions the foo() is the same.
>
>
> Yes.
>
> This appears to be x86-64 Unix code.

Yes. The godbolt server runs on x86-64 Linux, so that's what most of
its compilers generate. But it has compilers for ARM, MIPS, PPC, and
several other cpus as well if that's of interest.

(I've snipped the rest of your post - it's all good stuff, but I don't
need to comment on it.)

David Brown

unread,
Jan 18, 2017, 6:37:19 AM1/18/17
to
/Logically/, the compiler will create a temporary here. But the
compiler's optimisers will immediately hide it away - in cases like this
it can happen even when you don't specify optimisation options to the
compiler. The compiler is always free to generate whatever object code
it likes, as long as the visible results are the same as if it had
created all the temporaries, called all the functions, etc.

JiiPee

unread,
Jan 18, 2017, 9:36:34 AM1/18/17
to
On 18/01/2017 09:40, Robert Wessel wrote:
> This appears to be x86-64 Unix code.


its

x86-64 gcc 6.3

JiiPee

unread,
Jan 18, 2017, 9:43:01 AM1/18/17
to
On 18/01/2017 11:37, David Brown wrote:
> /Logically/, the compiler will create a temporary here. But the
> compiler's optimisers will immediately hide it away


But I am still thinking.. and I have this problem that how can I be sure
it will always hide that away?

Say I create a loop which runs 10 million times per second and i call
that function. I know that today it hides away that temporary, but what
about next year when I get a new compiler version... is it guaranteed to
do the same?? How can I be sure it does? Or do I need to next year also
double check its still hiding it away? You see my problem?


thats why I would kind of rather have something like:

forceinline int foo() {....}

So I can be sure in all versions it will surely inline it. and thus the
program runs the same in different platforms.

I think this is a similar problem to "is the integer size the same in
all platforms... how can I be sure int is the same size in the
furutere?" (well i know how to do that, but its a similar problem)

David Brown

unread,
Jan 18, 2017, 10:32:13 AM1/18/17
to
On 18/01/17 15:42, JiiPee wrote:
> On 18/01/2017 11:37, David Brown wrote:
>> /Logically/, the compiler will create a temporary here. But the
>> compiler's optimisers will immediately hide it away
>
>
> But I am still thinking.. and I have this problem that how can I be sure
> it will always hide that away?
>
> Say I create a loop which runs 10 million times per second and i call
> that function. I know that today it hides away that temporary, but what
> about next year when I get a new compiler version... is it guaranteed to
> do the same?? How can I be sure it does? Or do I need to next year also
> double check its still hiding it away? You see my problem?
>

I don't see why you are thinking of this as a problem.

Concentrate on writing /correct/ code. Put a little thought into how a
compiler might be able to optimise code - the more details the compiler
can see, the more efficient code it can produce. Learn to understand
and use the basic compiler flags for optimisation. Learn how to avoid
code constructs that appear to work on low optimisation but actually
have undefined behaviour that becomes apparent at higher optimisation.

Studying generated assembly is a good way to learn more about your
compiler, and to understand how it "thinks".

And then let the compiler do its job.

In some cases, different compiler versions will have regressions in
their speed, but it is not common. Usually they get better with newer
versions. And all compilers will get such basic stuff as this.

You only need to start worrying about the details of optimisation /if/
your code runs too slowly, and you have /measured/ it running too slowly
- or if you are writing such low-level code that lots of people will use
it in time-critical situations.

>
> thats why I would kind of rather have something like:
>
> forceinline int foo() {....}
>
> So I can be sure in all versions it will surely inline it. and thus the
> program runs the same in different platforms.
>

Compilers usually have extensions to give you that - you rarely need it.
You certainly don't need it here. Compilers generally do a better job
than humans at deciding what should be inlined.

> I think this is a similar problem to "is the integer size the same in
> all platforms...

No, that is about program correctness - not efficiency.

Bo Persson

unread,
Jan 18, 2017, 11:16:43 AM1/18/17
to
If we don't know what the next platform is, it is hard to decide on a
one-size-fits-all solution. Surely, if you are going to port the code
both to a smart watch and to a mainframe, the inlining decision will be
different.


Bo Persson

Vir Campestris

unread,
Jan 18, 2017, 4:01:34 PM1/18/17
to
On 18/01/2017 07:41, JiiPee wrote:
>
> But if I have a loop where I run some function 10 millions times this
> might become significant whether it inlines or not. And does the
> compiler understand this? Does it take account that I am running that
> inline code in such a loop? But it surely cannot always know what is the
> size of the loop. This is why I think it would be better to have a "pure
> inline" keyword which ALWAYS inlines. Because otherwise I have to go and
> check the assemply code to see what happened.... or time it. So that
> takes more development time to do that. Well, other option I have is to
> make a reference based function instead, but it just looks uglier.

You might like to read about "profile guided optimisation".

Things can be complex. If you inline functions it may be that your code
will no longer fit in the first level cache of the CPU. Or maybe the
second level. Or maybe even the RAM you have available.

I recall a guy from Microsoft saying that they build with optimise for
minimum size - because a page fault can ruin your day. (It will probably
take milliseconds to resolve, and you need a lot of performance
improvements to be worth that).

Andy
0 new messages