Hello, and welcome to C++ Weekly.
I'm your host, Jason Turner.
I'm available for code reviews, contracting,
and on site training.
Now, if you watched the last episode, and I hope you did,
I talked about GCC's support for the function attributes syntax
from C++ 14 and 17, that allows us to say,
I want to use this function attributes,
such as always in line and get some specific behavior from
the compiler and be able to do this in a portable way,
or at least mostly portable way if your compiler supports that
specific thing.
Now, there are many different function attributes in here.
And some of them are kind of goofy.
I mean, you've got constructors and destructors
that you can add to C, and it doesn't even make sense,
but that exists.
We've got warning and error attributes.
That's all cool.
But there's one here that I wanted to call out and show
the power of it.
I want to call attention to the pure function attribute here.
And this let us specify that the function has no external side
effects, and there is also another one
called const, that has to do with saying
that this function doesn't rely on any global values
or anything like that.
And it can allow GCC to emit more efficient code
for some calls to the function.
So we're going to play with this constant pure,
and see what the power is of them.
And this isn't const like in the C++ member function const kind
of sense.
This is different.
This is saying I don't to work with any global data
or any global state of the system at all.
So I'm going to start by making this simple just square
function.
And I'm not going to define it intentionally.
Now, let's go ahead and add also GCC and Clang here,
so we can see how and if they differ
in their handling of this code.
So we've got GCC and Clang and we're going to put them both
on full 03 optimization level.
So this is our general function here.
Now, the compiler has no way of knowing
what this function does, and that's intentional.
I intentionally am not giving it a body here.
Otherwise, it could optimize this far too
much for the sake of this example,
but it's calling this function square,
saving that value into r4, and then calling the function
square again, and it's adding the results of these things
together, r4 and r0.
Yeah, that's right, and then because it
has no way of knowing, like this square function
could be something like--
it simply has no way of knowing.
So we're going to take it back to this,
so that it doesn't know.
Now, using this function attribute
syntax, that GCC supports, we can
say this is a pure function.
It only relies on the values that have been passed to it.
And we can see immediately, right here,
that it's able to take this knowledge,
execute the square function once,
because this is argc here, and then do
a logical shift left by 1.
That means it's going to multiply it by 2,
so it gets the value that was from square,
multiplies it by 2, returns that out of main.
That's pretty cool.
Now, I don't expect that we're going
to see much difference with the const version.
No, for this code, it seems to stay the same.
But they are both different tools
that we can use to communicate with the compiler, hey,
by the way, these functions don't do anything
with global state.
You can optimize them in a better way
even if you can't inline them.
So hopefully, something like this
will actually get implemented in the standard,
and we'll have yet one more way to communicate to the compiler
and to the readers of our code what the nature is
of the functions that we are writing,
whether or not they use global state,
whether or not they're pure functions,
and give us all a little bit more information
when we're reading our code and when the compiler is attempting
to optimize it.
So thanks again for watching C++ Weekly,
and I hope you enjoyed this episode.