Hello again!
In this video, we are going to look at attributes.
Compiler writers have various directives.
These are things you can put in C++ source code, to make the compiler behave in various ways.
These have names like hash pragma, double underscore attribute and double underscore declspec.
These are not part of the C++ language.
They are compiler specific.
So these are used for things like: making the compiler generate certain types of code, laying out objects
in memory in a certain way, using conventions for calling functions. And so on.
C++11 introduced attributes, to provide a standard syntax for these compiler directives, and it also
defined a few attributes in the language. Which we can use in our own programs.
These attributes are meant to give extra information to the compiler. And they are not supposed to be
used to extend the language, or change the meaning of programs.
So they are nothing like Java attributes, which you can use for things like implementing database support.
The syntax for an attribute is that we use a pair of double square brackets. And then the attribute's name
goes inside that.
So this is how we would use the "noreturn" attribute.
If we are using an attribute in a declaration, it goes before the thing that it applies to.
Here we have a server() function, which is going to be no return.
So we put the noreturn attribute first, and then the server function prototype. You can use namespaces
with attributes.
So if you're working on the GNU compiler, you can put your directives in their namespace. So they will not
conflict with any other attributes.
And you can also provide arguments for attributes.
C++11 define the noreturn attribute.
This indicates that a function does not return.
Usually if you write a function which does not have a return statement, it means you made a mistake.
Often, compilers will give you a warning for that, so you can go back and fix it.
And that is usually helpful.
But sometimes, you do not actually want to return from the function.
For example, if we have a web server which just has a loop which keeps processing connections until
the program is terminated, then that function is never going to return.
So you do not really want the warning.
So you can say that this function is "noreturn".
It has the noreturn attributes.
That will also tell anyone reading the declaration that this function does not return, and it may help the
compiler generate better code.
C++11 also has the alignas keyword, which we looked at earlier.
This is not actually an attribute, but it is meant to replace the hash pragme pack. But it only works if the
argument is greater than the word size.
So here is our never ending function.
We use the no return attribute. And then we call the function, in the main() routine.
And there it goes.
There is no warning.
C++14 added the "deprecated" attribute.
Deprecated basically means "This code is going to go away soon, so stop using it!"
You could, for example, have a function where you have written a new version with a different interface.
You have not got around yet to changing all the code which calls this.
So you still need to have the old version.
But you want to discourage people who are writing new code from calling the old version.
You want them to use the new version.
So you could put the deprecated attribute in front of it.
And then anyone who calls this function will get a compiler warning, saying that this has been deprecated.
Which basically means you should try and use the new version. You can provide an argument, which will
be an explanation string, and the compiler will include that in its warning message.
So here is our deprecated function.
We have the "deprecated" attribute, with the explanation string.
So, "Please use the new version!" And then we call this.
And in fact, we get an error.
I am not sure that is correct.
The error message is just the text of the explanation string.
If we try this with g++, then we do get a warning.
It says that this function is deprecated. And then it gives the explanation.
So I think that is much clearer.
We have already mentioned the "fallthrough" attribute in C++17.
So this says that we intended to fall through from this case to this case.
It is not a mistake.
C++17 also has a "nodiscard" attribute.
So if you have this in front of a function, anyone who calls this function, and does not check the return
value, will get a compiler warning.
So sometimes, it does not really matter what a function returns. The printf() function,
for example. If you got a warning for not checking that, that would get really annoying!
But sometimes it does return something important, like an error code.
So you want to encourage people to look at the return value.
So here is our function, which returns something very important.
It has the nodiscard attribute.
And then we are going to call this function, and ignore the returned value.
So there we are.
We get the compiler warning. "Discarding return value of function with nodiscard attribute".
Attributes do not just apply to functions.
They can also be used with variables, types, members of structs, classes, enumerations, and so on.
With a type name, the attribute goes before the name of the type.
So if we have a struct Test, which is nodiscard, then we put "struct", then the attribute, then
the name of the struct.
So this will mean that any function which returns a Test object will be nodiscard.
So there is our struct Test, which is nodiscard.
This function returns a Test object.
So this function is, itself, nodiscard.
So if we call this without checking the return value, we should get the same warning again.
And we do.
And the last attribute we are going to look at is the "maybe_unused".
So if I just quickly remove
that, for a minute.
So we have a local variable here, which is not used and we get a warning for that: "unreferenced local variable".
And if I put this back, then the warning goes away.
So this could be useful if you have a function where you declare all the variables, but you want to
test the function before you have finished it.
So you may have some variables which are temporarily unused.
So this will get rid of annoying warnings.
Okay, so that is it for this video.
I will see you next time.
But until then, keep coding!