[dcl.attr.noreturn] provides the following example:
[[ noreturn ]] void f() {
throw "error";
// OK
}
but I do not understand what is the point of [[noreturn]], because the return type of the function is already void.
So, what is the point of the noreturn attribute? How is it supposed to be used?
The [[noreturn]] attribute is supposed to be used for functions that don't return to the caller. That doesn't mean void functions (which do return to the caller - they just don't return a value), but functions where the control flow will not return to the calling function after the function finishes (e.g. functions that exit the application, loop forever or throw exceptions as in your example).
This can be used by compilers to make some optimizations and generate better warnings. For example if f has the [[noreturn]] attribute, the compiler could warn you about g() being dead code when you write f(); g();. Similarly the compiler will know not to warn you about missing return statements after calls to f().
noreturn doesn't tell the compiler that the function doesn't return any value. It tells the compiler that control flow will not return to the caller. This allows the compiler to make a variety of optimizations -- it need not save and restore any volatile state around the call, it can dead-code eliminate any code that would otherwise follow the call, etc.
It means that the function will not complete. The control flow will never hit the statement after the call to f():
void g() {
f();
// unreachable:
std::cout << "No! That's impossible" << std::endl;
}
The information can be used by the compiler/optimizer in different ways. The compiler can add a warning that the code above is unreachable, and it can modify the actual code of g() in different ways for example to support continuations.
Previous answers correctly explained what noreturn is, but not why it exists. I don't think the "optimization" comments is the main purpose: Functions which do not return are rare and usually do not need to be optimized. Rather I think the main raison d'ĂȘtre of noreturn is to avoid false-positive warnings. For example, consider this code:
int f(bool b){
if (b) {
return 7;
} else {
abort();
}
}
Had abort() not been marked "noreturn", the compiler might have warned about this code having a path where f does not return an integer as expected. But because abort() is marked no return it knows the code is correct.
Type theoretically speaking, void is what is called in other languages unit or top. Its logical equivalent is True. Any value can be legitimately cast to void (every type is a subtype of void). Think about it as "universe" set; there are no operations in common to all the values in the world, so there are no valid operations on a value of type void. Put it another way, telling you that something belongs to the universe set gives you no information whatsoever - you know it already. So the following is sound:
(void)5;
(void)foo(17); // whatever foo(17) does
But the assignment below is not:
void raise();
void f(int y) {
int x = y!=0 ? 100/y : raise(); // raise() returns void, so what should x be?
cout << x << endl;
}
[[noreturn]], on the other hand, is called sometimes empty, Nothing, Bottom or Bot and is the logical equivalent of False. It has no values at all, and an expression of this type can be cast to (i.e is subtype of) any type. This is the empty set. Note that if someone tells you "the value of the expression foo() belongs to the empty set" it is highly informative - it tells you that this expression will never complete its normal execution; it will abort, throw or hang. It is the exact opposite of void.
So the following does not make sense (pseudo-C++, since noreturn is not a first-class C++ type)
void foo();
(noreturn)5; // obviously a lie; the expression 5 does "return"
(noreturn)foo(); // foo() returns void, and therefore returns
But the assignment below is perfectly legitimate, since throw is understood by the compiler to not return:
void f(int y) {
int x = y!=0 ? 100/y : throw exception();
cout << x << endl;
}
In a perfect world, you could use noreturn as the return value for the function raise() above:
noreturn raise() { throw exception(); }
...
int x = y!=0 ? 100/y : raise();
Sadly C++ does not allow it, probably for practical reasons. Instead it gives you the ability to use [[ noreturn ]] attribute which helps guiding compiler optimizations and warnings.
Related
Consider the two simple functions
void foo()
{
// do stuff
return;
}
void bar()
{
// do same stuff as foo()
}
where the only difference between them is foo() contains a return statement and bar() will return after "dropping" out of the function (for a lack of better terms). I assume that the return statement just represents a jump in assembly back to the stored address right before the function call. But I am curious to know if there are any performance differences between the two methods, other than the time it takes to type the 7 extra characters :).
No.
There is an implicit return at the end of a function with void return type, if you don't type it.
Don't concern yourself with how function calls and returns are implemented; you're currently in the realm of the abstraction that is C++. You're not programming a computer; you're describing a program. Your executable is not a one-to-one mapping of source code lines to computer instructions (not even close).
As it happens, there is no real-world performance difference whether you write return yourself or let it be implicit. Why would there be? The semantics are identical. They're the same program.
The compiler will always insert a RET instruction at the end of a void function (assuming it does not end by throwing an exception). An explicit return; statement here is not needed, and will have no effect.
The generated assembly in your example is identical:
foo():
ret
bar():
ret
(link to godbolt)
The explicit return from a function is useful to exit the function early. For example:
void foo() {
// do some work ...
if (/* some condition */)
return;
// do more work ...
}
Looking at the Standard (working draft, 8.7.4 The return statement [stmt.return], emphasis mine):
A function returns to its caller by the return statement.
The expr-or-braced-init-list of a return statement is called its operand. A return statement with no operand shall be used only in a function whose return type is cv void, a constructor, or a destructor. A return statement with an operand of type void shall be used only in a function whose return type is cv void.
[...]
Flowing off the end of a constructor, a destructor, or a non-coroutine function with a cv void return type is equivalent to a return with no operand. Otherwise, flowing off the end of a function other than main or a coroutine ([dcl.fct.def.coroutine]) results in undefined behavior.
There's no reason for a standard compliant compiler to generate different assembly codes for the two functions shown in the question, because they are equivalent.
So there won't be any perfomance difference, only different readability of the source code (unless you are following some weird code guideline, reviewers may very well ask you why a return statement is there).
Suppose the C++ below. Before calling of a->method1() it has an
assert (a) to check if a is sane.
The call a->method2() has no such assertion; instead method2 itself
checks for a valid this by means of assert (this).
It that viable code re. the C++ specification?
Even if it's covered by the standard, it not good style of course, and
it's error prone if the code ever changes, e.g. if the method is
refactored to a virtual method. I am just curios about what the
standard has to say, and whether g++ code words by design or just by
accident.
The code below works as expected with g++, i.e. the assertion in
method2 triggers as intended, because just to call method2 no
this pointer is needed.
#include <iostream>
#include <cassert>
struct A
{
int a;
A (int a) : a(a) {}
void method1 ()
{
std::cout << a << std::endl;
}
void method2 ()
{
assert (this);
std::cout << a << std::endl;
}
};
void func1 (A *a)
{
assert (a);
a->method1();
}
void func2 (A *a)
{
a->method2();
}
int main ()
{
func1 (new A (1));
func2 (new A (2));
func2 (nullptr);
}
Output
1
2
Assertion failed: this, file main.cpp, line 16
Even if it's [permitted] by the standard
It isn't.
it not good style of course
Nope.
and it's error prone if the code ever changes, e.g. if the method is refactored to a virtual method.
I concede that a virtual member function is more likely to cause a "crash" here, but you already have undefined behaviour and that's not just a theoretical concern: you can expect things like the assertion or conditions to be elided, or other weird things to happen.
This pattern is a big no-no.
I am just curios about what the standard has to say
It says:
[expr.ref/2] [..] For the second option (arrow) the first expression shall be a prvalue having pointer type. The expression E1->E2 is converted to the equivalent form (*(E1)).E2 [..]
[expr.unary.op/1] The unary * operator performs indirection: the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function to which the expression points. [..]
Notice that it doesn't explicitly say "the object must exist", but by saying that the expression refers to the object, it implicitly tells us that there must be an object. This sort of "gap" falls directly into the definition of undefined behaviour, by design.
whether g++ code words by design or just by accident.
The last one.
Answering your question up front: "C++: Is "assert (this)" a viable pattern?" - No.
assert(this); is pointless. The C++ standard guarantees that the this pointer is never nullptr in valid programs.
If your program has undefined behaviour then all bets are, of course, off and this might be nullptr. But an assert is not the correct fix in that case, fixing the UB is.
this cannot be nullptr, (else there is already undefined behavior).
in your case
a->method2(); // with a == nullptr
invokes undefined behavior, so checking afterward is useless.
Better signature to mean not null pointer is reference:
void func3(A& a)
{
a.method1();
}
int main ()
{
A a1(1); // no new, so no (missing) delete :-)
A a2(2);
func1(&a1);
func2(&a2);
func2(nullptr); :/
func3(a1);
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
casting unused return values to void
What is the purpose of (void) before a function call, for example
(void)func1();
I assume this is the same as simply calling func1();
Therefore is the (void) call simply to let other programmers know that the return type will be ignored, for instance if func1() had a return type of int, or does the compiler perhaps perform some optimizations on the function? Perhaps there is another reason behind it altogether - is it even legal C++ or perhaps is it a remnant of C seen in some legacy code.
Thanks
A cast to void can have semantic effect in one case: where a value is an operand of the comma operator and overrides the comma operator, a cast to void will suppress it:
struct S {
int operator,(int) { return 0; }
};
std::cout << (S(), 42) << '\n'; // prints '0'
std::cout << ((void) S(), 42) << '\n'; // prints '42'
It prevents warning if some function are declared with attribute : "Warn if return value not used/checked"
Maybe a duplicate of Warning: ignoring return value of 'scanf', declared with attribute warn_unused_result
Check the documentation of gcc : http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html (warn_unused_result) for more details
It means very little. It is explicitly turning the line to a void expression, that is an expression that is only used for its side effects and whose value is discarded. So the lines
func1();
and
(void)func1();
will do the same thing. There could be some optimization that can be performed if the compiler knows the value of the expression is not used, but it is likely that compiler can figure it out with or without the explicit (void).
It could be used as a form of documentation where the programmer is trying to make it obvious that they are not using the value of the expression.
Another strange use is to allow the function of unknown return type to be used adjacent to the , operator as a sequence operator. Ie, decltype( f(), g() ) technique, where you want to say "f can be operated on with (), as can g, and I want this type to be the type that g() returns". However, if f() returns a type such that operator, is overloaded, the result will be unexpected.
So you do decltype( void(f()), g() ), and discard the return value of f() before invoking operator,, so you are guaranteed to get the built-in sequence operator instead of some unknown override type.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
casting unused return values to void
What is the purpose of (void) before a function call, for example
(void)func1();
I assume this is the same as simply calling func1();
Therefore is the (void) call simply to let other programmers know that the return type will be ignored, for instance if func1() had a return type of int, or does the compiler perhaps perform some optimizations on the function? Perhaps there is another reason behind it altogether - is it even legal C++ or perhaps is it a remnant of C seen in some legacy code.
Thanks
A cast to void can have semantic effect in one case: where a value is an operand of the comma operator and overrides the comma operator, a cast to void will suppress it:
struct S {
int operator,(int) { return 0; }
};
std::cout << (S(), 42) << '\n'; // prints '0'
std::cout << ((void) S(), 42) << '\n'; // prints '42'
It prevents warning if some function are declared with attribute : "Warn if return value not used/checked"
Maybe a duplicate of Warning: ignoring return value of 'scanf', declared with attribute warn_unused_result
Check the documentation of gcc : http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html (warn_unused_result) for more details
It means very little. It is explicitly turning the line to a void expression, that is an expression that is only used for its side effects and whose value is discarded. So the lines
func1();
and
(void)func1();
will do the same thing. There could be some optimization that can be performed if the compiler knows the value of the expression is not used, but it is likely that compiler can figure it out with or without the explicit (void).
It could be used as a form of documentation where the programmer is trying to make it obvious that they are not using the value of the expression.
Another strange use is to allow the function of unknown return type to be used adjacent to the , operator as a sequence operator. Ie, decltype( f(), g() ) technique, where you want to say "f can be operated on with (), as can g, and I want this type to be the type that g() returns". However, if f() returns a type such that operator, is overloaded, the result will be unexpected.
So you do decltype( void(f()), g() ), and discard the return value of f() before invoking operator,, so you are guaranteed to get the built-in sequence operator instead of some unknown override type.
void f() means that f returns nothing. If void returns nothing, then why we use it? What is the main purpose of void?
When C was invented the convention was that, if you didn't specify the return type, the compiler automatically inferred that you wanted to return an int (and the same holds for parameters).
But often you write functions that do stuff and don't need to return anything (think e.g. about a function that just prints something on the screen); for this reason, it was decided that, to specify that you don't want to return anything at all, you have to use the void keyword as "return type".
Keep in mind that void serves also other purposes; in particular:
if you specify it as the list of parameters to a functions, it means that the function takes no parameters; this was needed in C, because a function declaration without parameters meant to the compiler that the parameter list was simply left unspecified. In C++ this is no longer needed, since an empty parameters list means that no parameter is allowed for the function;
void also has an important role in pointers; void * (and its variations) means "pointer to something left unspecified". This is useful if you have to write functions that must store/pass pointers around without actually using them (only at the end, to actually use the pointer, a cast to the appropriate type is needed).
also, a cast to (void) is often used to mark a value as deliberately unused, suppressing compiler warnings.
int somefunction(int a, int b, int c)
{
(void)c; // c is reserved for future usage, kill the "unused parameter" warning
return a+b;
}
This question has to do with the history of the language: C++ borrowed from C, and C used to implicitly type everything untyped as int (as it turned out, it was a horrible idea). This included functions that were intended as procedures (recall that the difference between functions and procedures is that function invocations are expressions, while procedure invocations are statements). If I recall it correctly from reading the early C books, programmers used to patch this shortcoming with a #define:
#define void int
This convention has later been adopted in the C standard, and the void keyword has been introduced to denote functions that are intended as procedures. This was very helpful, because the compiler could now check if your code is using a return value from a function that wasn't intended to return anything, and to warn you about functions that should return but let the control run off the end instead.
In imperative programming languages such as C, C++, Java, etc., functions and methods of type void are used for their side effects. They do not produce a meaningful value to return, but they influence the program state in one of many possible ways. E.g., the exit function in C returns no value, but it has the side effect of aborting the application. Another example, a C++ class may have a void method that changes the value of its instance variables.
void() means return nothing.
void doesn't mean nothing. void is a type to represent nothing. That is a subtle difference : the representation is still required, even though it represents nothing.
This type is used as function's return type which returns nothing. This is also used to represent generic data, when it is used as void*. So it sounds amusing that while void represents nothing, void* represents everything!
Because sometimes you dont need a return value. That's why we use it.
If you didn't have void, how would you tell the compiler that a function doesn't return a value?
Cause consider some situations where you may have to do some calculation on global variables and put results in global variable or you want to print something depending on arguments , etc.. In these situations you can use the method which dont return value.. i.e.. void
Here's an example function:
struct SVeryBigStruct
{
// a lot of data here
};
SVeryBigStruct foo()
{
SVeryBigStruct bar;
// calculate something here
return bar;
}
And now here's another function:
void foo2(SVeryBigStruct& bar) // or SVeryBigStruct* pBar
{
bar.member1 = ...
bar.member2 = ...
}
The second function is faster, it doesn't have to copy whole struct.
probably to tell the compiler " you dont need to push and pop all cpu-registers!"
Sometimes it can be used to print something, rather than to return it. See http://en.wikipedia.org/wiki/Mutator_method#C_example for examples
Functions are not required to return a value. To tell the compiler that a function does not return a value, a return type of void is used.