Where is the return value of fn called when ignored?

I just saw a snippet of code in Dive into Python where a function called another function (which actually returns something other than None ) and still the calling function does NOT assign the return value to the variable.

I was alarmed by this and quickly went to try:

 >>> def foo(): return "hello_world!" ... >>> def bar(): foo() ... 

I understand that every function in python returns (either None or something else)

To my surprise, when I tried the same logic in my previously learned languages, they seem to exhibit similar behavior:

C:

 #include<stdio.h> char* foo(){return "hello_world!";} int main(void){ foo(); // works! return 0; } 

C++

 #include<iostream> #include<string> using namespace std; string foo(){return "hello_world!";} int main(){ foo(); // works! return 0; } 

Java:

 public class Test{ public static String foo(){return "hello_world!";} public static void main(String args[]){ foo(); // works! System.exit(0); } } 

All this time I assumed that the function really returns something, it MUST be set to some variable, otherwise, where would the value be returned ?!

+7
source share
3 answers

He is disappearing.

In the case of languages ​​and runtimes in which the object to be collected for garbage collection is returned, the result of calling this function is suitable for collection as soon as the function returns.

In the case of languages ​​and runtimes that return an object that is counted by reference or similarly protected in order to force an immediate cleanup when the object is no longer needed, this cleanup will occur when the function returns.

Otherwise, the value is simply lost. There was no harm done and should be completely safe.

+7
source

All this time I assumed that the function really returns something, it MUST be set to some variable, otherwise, where would the value be returned ?!

It goes into bit-bit. wikipedia article: http://en.wikipedia.org/wiki/Bit_bucket

Example:

 std::set<std::string> set_of_strings; ... set_of_strings.insert (some_string); 

Here std::set::insert() returns a std::pair , an iterator pointing to the element in the set and bool indicating whether the element was added. In this case, the returned std::pair will just disappear. In many cases, you don't care if an element with the same value is present. In such cases, there is no reason to check the second return value. In many cases, you also do not care about the iterator. So just let it go.

Some overly pedantic programmers will introduce the following:

 std::set<std::string> set_of_strings; ... (void) set_of_strings.insert (some_string); 

(void) supposedly tells the compiler to ignore the return result. However, the compiler does not need to report this. It will ignore the return result if it is not used. What is supposed (void) is to tell code readers that the return value is intentionally ignored.

However, you will never do this:

 (void) x = 42.0; (void) a = b = c = 42; 

Both of these assignment operators return a value. (You would not be able to say a = b = c = 42 if this is not so.) This is just one of many examples showing that you always send data to a bucket of bits without knowing it.

My recommendation: Do not use (void) to declare that you intentionally ignore the return result. He doesn’t need a compiler, he doesn’t need a reasonable code reader, and it just makes the programmer who wrote it look arrogant know-how, which most likely knows a lot less than they think.

+4
source

In case C, the implementation is dependent. Often, the result of a function is pushed onto the machine register rather than onto the stack. It depends on whether it is used or not.

0
source

All Articles