1

I recently learned about the [[noreturn]] attribute and wanted to try and implement it on one of my existing code snippets.

I added the attribute to a void return type function with no return; keyword on it whatsoever. However, I'm getting this error:

[ 17%] Building CXX object CMakeFiles/Renderer.dir/src/opengl/text_render.cpp.o
/home/turgut/Desktop/CppProjects/videoo-render/src/opengl/text_render.cpp:7:25: error: function ‘const void OpenGL::Text::set_background(int, int, float, int, int, int, int, float, std::string*)’ declared ‘[[noreturn]]’ but its first declaration was not
    7 | [[noreturn]] const void Text::set_background(
      |   

make[2]: *** [CMakeFiles/Renderer.dir/build.make:132: CMakeFiles/Renderer.dir/src/opengl/text_render.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:277: CMakeFiles/Renderer.dir/all] Error 2
make: *** [Makefile:136: all] Error 2

I'm using c++ 20+ so I don't think there is a problem with versions.

What is wrong with my usage of [[noreturn]] and how should I use it propperly? Am I missing a piece of knowledge about it?

Here is the function in question:

[[noreturn]] void Text::set_background(
    int x, int y, float z,
    int w, int h, 
    int gw, int gh,
    float ang, std::string* hex_color
){
    background = new Background(x-w, y-h);
    background->color = (*hex_color).c_str();

    background->bg_texture = new Texture(
        x - 10, (1000 - y) + 10, w, -h ,gw, gh
    );

    background->bg_texture->init(ang, z, nullptr);
}

I've also tried to use it on some other similar functions but got a similar result.

Turgut
  • 711
  • 3
  • 25
  • 2
    the error complains about the first declaration which you did not include in the quesiton – 463035818_is_not_an_ai Nov 04 '22 at 07:44
  • 2
    i'd expect the complete error message to contain something along the line of "first declared here ...." with the declaration and line number. Better include the complete error message in questions – 463035818_is_not_an_ai Nov 04 '22 at 07:47
  • 1
    Your function returns, so why you add the attribute? It is not about void or not, it is about the function will never ends. – Klaus Nov 04 '22 at 07:49
  • 1
    minimal complete example: https://godbolt.org/z/cjWbaedPn – 463035818_is_not_an_ai Nov 04 '22 at 07:54
  • What happens if `set_background` is called a second time on the same object? More specifically, what happens with the previous `background` object? Why do you even use pointers? What problem are all those pointers supposed to solve? Perhaps you come from a C# or Java background, where `new` must be used to create objects? That's not needed in C++. Perhaps you might need to invest in [some good C++ books](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list/388282#388282)? – Some programmer dude Nov 04 '22 at 07:55
  • @463035818_is_not_a_number It does not say "first declared here", I've updated the question to include the full error message. – Turgut Nov 04 '22 at 08:12
  • @463035818_is_not_a_number I've updated it. – Turgut Nov 04 '22 at 08:14
  • @Turgut The godbolt link above shows that that output is the first half of a GCC error, and the second half, which is missing from yours, shows where the declaration is. I wonder why your makefile is only showing the first half of the error – Mooing Duck Nov 04 '22 at 08:18
  • @MooingDuck There were a lot of errors on other files, so I made sure to cut the unnecessery parts only, I've used grep to make sure that there were no `first implemented here` errors, plus using Some programmer dude 's answer helped me fix it. There was another issue which I'm going to post an answer about. – Turgut Nov 04 '22 at 08:26
  • 1
    *"a void return type function with no `return;` keyword on it whatsoever"* -- you might want to review some [notes for `return`](https://en.cppreference.com/w/cpp/language/return#Notes): "If control reaches the end of a function with the return type (possibly cv-qualified) `void` [or ...] without encountering a return statement, `return;` is executed." So while the keyword is not present, there is still an implied `return;` (*because* you chose a void-returning function). – JaMiT Nov 04 '22 at 08:28
  • @Turgut: In my tests, the error message is now `note: previous declaration is here` – Mooing Duck Nov 04 '22 at 14:56

2 Answers2

7

The attributes needs to be in the actual declaration of the function, the one you have in the header file inside the Text class.

For the definition (implementation) of the function you don't need to use the attribute again.


On a couple of different notes, using the const qualifier for a void return type makes no sense.

And the [[noreturn]] attribute is to tell the compiler that the function doesn't return at all. For example the std::exit function doesn't return and is thus marked with that attribute.

You function do return (I assume?) so the attribute makes no sense for that function.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Yea, the phrase 'It does not return at all' makes a lot of sense, I guess I should add it to a main-like function or a function that has an exit. Thanks! And yea I have removed the const lol. – Turgut Nov 04 '22 at 08:10
  • 1
    You should not add it to `main` because `main` returns. – Mooing Duck Nov 04 '22 at 08:19
0

There were 2 issues about this error code, first is what Some programmer dude have posted. The other is that I forgot to add the same attribute to both header and the cpp file.

So it had to be put on both the implementation and the declaration.

Turgut
  • 711
  • 3
  • 25
  • The `[[noreturn]]` atribute is not to mark functions without an explicit `return` statements. It's to mark functions that doesn't go back to the caller *at all*. A function which exits the process fall into that category, a thread-function with an infinite loop that will never be broken out of as well. A function which goes back to the calling function, with or without an explicit `return` statement, still *returns* (the return might be implicit). If you call your function, and expect to continue after that function finishes, you should not use that attribute. – Some programmer dude Nov 04 '22 at 09:03
  • @Someprogrammerdude I have a question, will it effect destruction? Like if we enter a function that has an infinite loop in it an does not return to its caller, when we eventually close the program how will it handle destruction? Like my `noreturn` function is a part of a class, when my program is done, I want to delete that class inside my main function. How will it handle that? – Turgut Nov 04 '22 at 10:12
  • There's no destruction. The process is just killed and the OS will (hopefully) release all resources. If you have such a function, then it needs to be designed with this in mind, and not do anything that can lead to corrupted files or similar. – Some programmer dude Nov 04 '22 at 10:22
  • @Someprogrammerdude Got it, so I have design in such a way that the program will stop executing at the end of the function in question. – Turgut Nov 04 '22 at 11:36