Welcome to C++ Weekly.
I'm your host Jason Turner.
I'm available for code reviews, contracting,
and on-site training.
Now, in this episode, I'm going to discuss very briefly
GNU function attributes.
Now, I want to be clear that, for the most part,
I try very hard to avoid using compiler-specific extensions
and attributes in my code, because they're not portable.
And I have to, 99% of the time, be very much concerned about
the portability of my C++ code, where I'm supporting many
architectures at once with many different compilers.
And this is something that I advocate
that everyone do, if you can, because it gives you
much more robust code.
And you have a stronger guarantee that you're actually
using well-defined C++, when it compiles incorrectly and passes
all of your tests on multiple compilers.
So that said, I just wanted to bring up these GNU function
attributes.
Now, this is a rather large set of things.
This is available easily on the GCC website,
and we've got common attributes, and then
we've got attributes for basically every single CPU
architecture that GCC supports.
I'm going to go into the Common Function attributes,
and the one that I am most likely to see
in code that I'm looking at is this, always inline.
And it says, generally, functions
are not inlined unless optimization is specified.
For functions declared inline, this attribute
inlines the function independent of any restrictions that
otherwise apply to inlining.
So basically, you're kind of forcing the compiler
to inline a function.
And again, if you saw my most recent episode
on function inlining, I strongly recommend
that you trust the compiler.
But I wanted to bring this up to give
a quick example about these function attributes.
So if you've watched C++ Weekly at all,
you should not be surprised that this code has gotten inlined
into main, this add function got inlined into main,
plus some optimizations taking into account this plus two
for the argc here.
So we're basically adding argc plus argc plus two,
and it's doing something like this here.
So let's go ahead and pull back our optimizations.
If we go back to 01, then we can see that main is actually
calling the add function here.
Now, the always inline attribute is going
to look something like this.
So even though we have optimizations down at 01,
we are telling the compiler, yes,
I very much want you to always inline this.
And the compiler is going to dutifully do that,
end it, inlines it, and it's no longer
an actual function call to add.
So for review, take this out, and we
can see that it is actually branching to the function add.
Put it back in, and we can see that it
is inlining the add right here.
Now, this is non-standard syntax that
is kind of compiler-specific.
If we really needed to do this, we
might have to do something like--
might have to do something like this
to put that attribute before here, if we're
doing like cross platform code or something.
But there is a solution that does not
have to rely on compiler-specific behavior,
and that is why I am bringing this up in this episode,
because I'm always about portability.
So we're back to this version.
We're calling this branch to this add here,
but we want to use syntax that is standard in C++,
and it turns out that we can.
If we use the C++ 11 14 attribute syntax here with
these double brackets, we can specify we want something from
the GNU namespace, and we want always inline here,
and it does exactly we wanted it to do.
Now, depending on your compiler version,
you might get some error or warning saying,
I don't know that attribute, but I'm going to fail to compile.
But in C++ 17, the compiler is required to accept attributes
that it doesn't know.
So if you really wanted to-- which by the way,
this attribute is accepted by Clang or GCC,
so it's got Clang and GCC going on here.
This has been actually the Clang one this entire time.
You could, hypothetically, do something like--
and the compiler is required to ignore the one that it doesn't
know, and we get a warning here saying,
unknown attribute always inline.
So you might have to do a little bit of conditional code
or something, but in my opinion, the syntax is much cleaner,
and it's portable and probably something to consider,
if you need to do this in the future.
So again, I do not recommend using
the always inline attribute.
I do recommend relying on your compiler to do the right thing.
But if you have a reason to use some of these compiler-specific
attributes, I do strongly recommend that you use the new
syntax that C++ 14 and 17 affords us and get something
that is a little bit more portable.
So as always, thanks for watching.