Difference between return 0 and -1 [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
Can anyone please explain the difference between return 0 and -1 used in c++? I have read many articles and posts from other programmers saying that return 0 means the program is successful and -1 means the program has an error. But what I don't get is why use these statements when the compiler will generate an error if there is one in the program anyway? Please explain in detail what these statements really mean.

This has absolutely nothing to do with the compiler.
The compiler will report syntax errors.
The return codes are used to report if the program completed successfully.
("Success" depends on what the program was intended to do).
For example:
// Program SearchTerm "term to find"
int main(int argc, char* argv[])
{
bool search_successful = false;
[ ... do work ... ]
if (search_successful)
{
return 0; // The search worked.
}
else
{
return -1; // The search failed
}
}
Example usage:
SearchTerm "Microsoft"
More than 1 million results found... returned Success
SearchTerm "asldfjpu"
No results found... returned Failure
When a program reports success or failure, it can be integrated in the Scripts such as:
#!/bin/bash
if `SearchTerm "Microsoft"`; then
GetTopResults "Microsoft"
else
echo "No results found, no Top Results to retrieve"
fi

The return value of int main() is the so called exit code of the program. This is already so in C (which has no exceptions) and is there to basically tell to caller how it went. A exit code of zero means success and every other exit code (but normally one uses only positive ones) means that something went wrong. Sometimes programms will document what a certain exit code means i.e. if a file was not found or an allocation failed etc.
This is a very important part of scripting for example bash scripts, which know in this way if a called command went right or wrong. Even if your program crashes with an exception, the programm will generate an exit code (which will be non-zero). In bash you can see the exit code of the last run program with echo $?, so you can check that out for yourself.

A return is simply the value returned by any function. At the end of a function, the computer is able to accept a single value to take back with it when it returns to the rest of the program. In the case of the function int main(), with which you are probably familiar, the return value is used as an indication of the success of the program.
main() is simply the entry point of the program you are running. It's the first function called by your computer when the program starts (with some exceptions)
Theoretically, you could return any integer from main().
The only "accepted" thing is that anything that is non-zero is generally some error or fault. So a return 0; indicates success, while return -1; might indicate some kind of error. The truth is, the value returned from main() doesn't really matter, and won't affect how your program runs.

If you're asking about the value returned by main, there are two defined values that you can return: EXIT_SUCCESS and EXIT_FAILURE. Those values are defined in the header <stdlib.h> and in the header <cstdlib>. You can also return the value 0, which is equivalent to returning EXIT_SUCCESS. There are no other meaningful values in C or C++, although your implementation can provide meanings for other values.

I am assuming that you are returning 0 or -1 from the main program as your program exits. What this does is inform the calling program the success or failure of the program. This is not very handy if you just run the program at a command prompt but if your program is called within a script (Perl,PHP, python, PowerShell, etc) you can test to see if the program was successful.
In a nutshell, if your program is called by another program, the calling program can test for success or failure and respond appropriately.

the program is successful and -1 means the program has an error.
Please explain in detail what these statements really mean.
There are situations where a function cannot proceed further, and cannot complete the task that it is specified for it. Such situation is typically called an error. There are many possible sources of errors. One example of that is a function that has pre-conditions for the inputs that were not satisfied by the caller of the function. An example of such pre-condition is square root function that calculates rational numbers (i.e. not complex): There is no result for negative input.
When an error is encountered, it must somehow be communicated to the caller. There are many techniques, but we shall not cover all of them in detail here. I'll mention that one option in C++ is exceptions. Exceptions technique has some useful properties, but it is not universally applicable to all situations.
Another, very simple technique is to return an error code which is an integer value. If we choose 0 to signify no error, the caller of the function can check for error with following pattern:
int error = function(arguments)
if (error) {
// handle error here
}
This pattern is very common in C APIs. C++ inherits C standard library, and it is common to take advantage of C libraries so it is common to encounter this in C++ as well.
Sometimes, a function needs to use the return value for some other purpose. For example, the open call from POSIX standard returns an integer called "file descriptor", which is a positive integer. Since some of the values in the domain of the return type are not used (negative numbers), it can be used to represent error condition as well. Although any negative number is available, -1 was chosen, and this is also quite conventional. In some other APIs different negative numbers represent different errors. Another approach is to store error information elsewhere. The chosen approach in POSIX is to store the error code in a separate variable.
In conclusion: Integer return values are a technique of communicating errors, and 0 is conventionally used to represent success and -1 is often used to represent erroneous execution. The meaning of the return value of a function should be documented by the implementer, and the documentation should be studied carefully by the user of the function.
But what I don't get is why use these statements when the compiler will generate an error if there is one in the program anyway?
It's unclear what you expect here. The compiler cannot read the programmer's mind and know all cases where the program should have an error. It can only tell whether the program is well-formed or not (and maybe give some helpful warnings about obvious mistakes if you're lucky).
It is the programmer's responsibility to consider the error conditions of the program.

The only difference between 0 and -1, as far as the compiler is concerned, is that they are two different numbers. Nothing is assumed whatsoever about their "success" or "failure" status (except in main in which the return value is ignored anyway).
The rest are (mostly bad) conventions used by developers. Usually < 0 for failure and 0 for success and you have created a nice bug when you test against bool (in which -1 is true and 0 is false).
One should use enums or, at least, something more recognizable as in windows HRESULT.

It basically means that anything other then 0 means something bad happened during execution of your program. The program could not deal with it so it exited with the status code.
Often when working with shell you will notice that some of commands exit with non 0 status code. You can check that value by running echo $? command.
And finally you can use return codes to communicate to the client what happend. That is if you describe what return codes can your program return.

Related

Which one is preferred when checking arguments? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
For example, I have a method which accepts some arguments like
method1(int i)
the argument int should be either 1 or 2
I can use assert (i == 1 || i ==2)
or throw exception if (!(i==1) || (i==2)) throw std::exception
which one is better. I am always confused about assert vs explicit throw.
It really depends on the situation.
There are four major groups of error handling:
assert - used to deal with programming errors ("We don't expect this function to get a NULL pointer, and if it does, it's because some other part of our code is broken, and it should NEVER happen"). If the assert wasn't there, the code would probably crash, loop forever, or otherwise "fail".
exceptions - such as std::invalid_argument - this is more used when the program EXPECTS things to go wrong, and there is some way to "try again". More likely when the actual user is using the program wrong - e.g. inputs from keyboard/file, etc. As the name states, this should be an "exception" - something unusual and unexpected.
return value - when an error is entirely likely (trying to see if the serial port is on port COM1, COM2, COM3 or COM4 or "is the result of the equation matching what I expect yet?")
Let it crash - if the inputs are wrong, the application runs out of memory, etc, just crash. It may seem like a rough method, but sometimes there's not much better you can do anyway - what are you going to ACTUALLY do in the middle of your compiler if some linked list is broken and the next node is not pointing at your special sentry pointer, but to NULL? Printing a message may be a little better, but not a huge amount.
Is the integer passed to method1 always going to be done so by a programmer, or might it be passed in by the users of your application?
Assert,
for example if your code looks like this:
int i;
if ( condition ) {
i = 1;
}
else {
i = 3;
}
method1(i);
If this is the case, you'd likely want to use an assert, because it indicates you (the programmer) has made an error. If i = 3, you want your program to blow up and make it obvious there is a problem in your code, so you can catch it before you release it to your clients.
Throw an exception,
on the other hand, if your code looks like this:
int i;
cin >> i;
method1(i);
You're passing the user's input to the function. You can't anticipate what they might enter. So if it's an invalid value, you should throw an exception or return an error code and handle it accordingly (e.g., print out a message to the user saying they have entered an invalid number).
Generally asserts are checked in debug builds but not release builds. If you want to save time and skip the check in your final released code, then asserts are the way to go. If your function needs to blow up in the face of unexpected input even in release, then the exception may be the way to go.
Of course the details of exactly what you should do for error conditions will vary with context beyond what was provided in your example.

Clarifying Return 0 and 1

So returning 0 in a function (Not main) means false and returning 1 or anything but 0 means success.
Why in the main() function do we put 0, meaning there were no errors when 1 in other functions mean it ran successfully, thanks.
0 and 1 (or any non-zero number) convert to the boolean values false and true in a context where a conversion to bool happens, e.g. in if(here) .... This is used within your program.
The return value from main is used in a different way, it is returned to the shell that called the program. In the shell's context the value is interpreted differently. There, 0 traditionally means "no error" while values larger than zero indicate errors and the value itself contains some hints as to what kind of error occurred. Take this snippet from man grep:
EXIT STATUS
The grep utility exits with one of the following values:
0 One or more lines were selected.
1 No lines were selected.
>1 An error occurred.
Returning a certain number does not mean anything by default.
The developer decides what a method returns and what the returned value means.
main returns an exit code and 0 for no error which is kind of straight forward and there are a lot more possible return values that just 0 and 1.
There is no standard on which value represents failure and which represents success. However, traditionlly, C/C++/Unix choose to use 0 as success and non-zero for failure, because the non-zero value can be used as error code to represent a variety of failure reasons.
Think of it this way:
By tradition, no function ever returns a boolean indicating success. Instead, the return type is either some error number or some object pointer.
Now, if an error code is returned and no error occurs, naturally no error is returned. This is the meaning of zero when main() returns. Consequently, if(main()) means something like if(error).
Likewise, if an object pointer is returned, and an error occurs, no object can be returned, which again is indicated by zero (= a null pointer). So, if(getObject()) means something like if(/*getObject() actually returned something*/).
So, even though it looks the wrong way round, it is not. It's just that nothing ever directly returns a success boolean.
Returned value for itself means nothing, developers decide if that value means error or not.
But take a look at error codes and their handling.
int MyFunctionWhichCanFail(...)
{
/*some code*/
return ERROR_CODE;
}
int FunctionWhichWorksWithFunctionWhichCanFail()
{
if (MyFunctionWhichCanFail(...))
{
//some error handling
}
//other stuff
}
In this case it is possible to occur many different errors, so error code is very good option, in cases there possible result failure/success is better use bool.
Also I want to note, that in most systems zero is defined as ERROR_SUCCESS (or some other keyword which means success).

Should I unit-test with data that should not be passed in a function (invalid input)?

I am trying to use TDD for my coding practice. I would like to ask should I test with a data that should not happen in a function BUT this data may possibly break your program.
Here is one of a easy example to illustrate to what I ask :
a ROBOT function that has a one INT parameter. In this function I know that the valid range would only be 0-100. If -1, 101 is used, the function will be break.
function ROBOT (int num){
...
...
...
return result;
}
So I decided some automated test cases for this function...
1. function ROBOT with input argument 0
2. function ROBOT with input argument 1
3. function ROBOT with input argument 10
4. function ROBOT with input argument 100
But should I write test cases with input argument -1 or 101 for this ROBOT function IF I would guard that in my other function that call function ROBOT???
5. function ROBOT with input argument -1
6. function ROBOT with input argument 101
I don't know if it is necessary cause I think it is redundancy to test -1 and 101. And If it is really necessary to cover all the cases, I have to write more code to guard -1 and 101.
So in Common practice of TDD, will you write test case on -1 and 101 as well???
Yes, you should test those invalid inputs. BUT, if your language has accessibility modifiers and ROBOT() is private you shouldn't be testing it; you should only test public functions/methods.
The functional testing technique is called Boundary Value Analysis.
If your range is 0-100, your boundary values are 0 and 100. You should test, at least:
below the boundary value
the boundary value
above the boundary value
In this case:
-1,0,1,
99,100,101
You assume everything below -1 to -infinity behaves the same, everything between 1-99 behaves the same and everything above 101 behaves the same. This is called Equivalence Partitioning. The ranges outside and between the boundary values are called partitions and you assume that they will have equivalent behaviour.
You should always consider using -1 as a test case to make sure nothing funny happens with negative numbers and a text string if the parameter is not strongly typed.
If the expected outcome is that an exception is thrown with invalid input values, then a test that the exceptions get properly thrown would be appropriate.
Edit:
As I noted in my comment below, if these cases will break your application, you should throw an exception. If it really is logically impossible for these cases to occur, then I would say no, you don't need to throw an exception, and you don't need test cases to cover it.
Note that if your system is well componentized, and this function is one component, the fact that it is logically impossible now doesn't mean it will always be logically impossible. It may be used differently down the road.
In short, if it can break, then you should test it. Also validate data at the earliest point possible.
The answer depends on whether you control the inputs passed to Robot. If Robot is an internal class (C#) ; values only flow in from RobotClientX which is a public type. Then I'd put the guard checks in RobotClientX, write tests for it. I'd not write tests for Robot, because invalid values cannot materialize in-between.
e.g. if I put my validations in the GUI such that all invalid values are filtered off at the source, then I don't check for invalid values in all classes below the GUI (Unless I've also exposed a public API which bypasses the GUI).
On the other hand, if Robot is publicly visible i.e. Anyone can call Robot with any value that they please, then I need tests that document it's behavior given specific kinds of input.. invalid being one of them. e.g. if you pass an out-of-range value, it'd throw an ArgumentException.
You said your method will raise an exception if the argument is not valid.
So, yes you should, because you should test that the exception gets raised.
If other code guards against calling that method incorrectly, and no one else will be writing code to call that method, then I don't see a reason to test with invalid values. To me, it would seem a waste of time.
The programming by contract style of design and implementation draws attention to the fact that a single function (method) should be responsible for only some things, not for everything. The other functions that it calls (delegates to) and which call it also have responsibilities. This partition of responsibilities is at the heart of dividing the task of programming into smaller tasks that can be performed separately. The contract part of programming by contract is that the specification of a function says what a function must do if and only if the caller of the function fulfills the responsibilities placed on the caller by that specification. The requirement that the input integer is within the range [0,100] is that kind of requirement.
Now, unit tests should not test implementation details. They should test that the function conforms to its specification. This enables the implementation to change without the tests breaking. It makes refactoring possible.
Combining those two ideas, how can we write a test for a function that is given some particular invalid input? We should check that the function behaves according to the specification. But the specification does not say what the function must do in this case. So we can not write any checks of the program state after the invalid function call; the behaviour is undefined. So we can not write such a test at all.
My answer is that, no, you don't want exceptions, you don't want to have to have ROBOT() check for out of range input. The clients should be so well behaved that they don't pass garbage values in.
You might want to document this - Just say that clients must be careful about the values they pass in.
Besides where are you going to get invalid values from? Well, user input or by converting strings to numbers. But in those cases it should be the conversion routines that perform the checks and give feedback about whether the values are valid or not. The values should be guaranteed to be valid long before they get anywhere near ROBOT()!

What is the purpose of the returning of a value from main() in C/C++? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
main() functions return value?
What should main() return in C/C++?
What is the purpose of the returning of a value from main() in the languages C and C++?
How the return value helps us?
Can the return value be used to achieve anything important?
It's the exit status. It's typically used to signal to the OS whether the process was successful or not in whatever it was doing.
It indicates the execution status of the program. Usually zero means it went fine.
On most operating systems, the return value becomes the value returned from the process when it exits. By convention, a return value of zero signifies a normal exit, while non-zero values signify different abnormal termination conditions.
This value can be tested by most command shells. For instance, in bash, the $? variable holds the return code of the last program. Also, its && and || operators determine whether to execute the right hand side, based on whether the left hand side signal a normal exit or not:
# Fetch the images, and only process them if the fetch succeeded (return code 0).
fetch-images && process-images
In command line environment, the return value signifies success or failure of the program run. This way you can share some status information with the caller. Zero is reserved to be success in Unix.
A more detailed answer can also be found here.
More Details

What type of input check can be performed against binary data in C++?

let's say I have a function like this in C++, which I wish to publish to third parties. I want to make it so that the user will know what happened, should he/she feeds invalid data in and the library crashes.
Let's say that, if it helps, I can change the interface as well.
int doStuff(unsigned char *in_someData, int in_data_length);
Apart from application specific input validation (e.g. see if the binary begins with a known identifier etc.), what can be done? E.g. can I let the user know, if he/she passes in in_someData that has only 1 byte of data but passes in 512 as in_data_length?
Note: I already asked a similar question here, but let me ask from another angle..
It cannot be checked whether the parameter in_data_length passed to the function has the correct value. If this were possible, the parameter would be redundant and thus needless.
But a vector from the standard template library solves this:
int doStuff(const std::vector<unsigned char>& in_someData);
So, there is no possibility of a "NULL buffer" or an invalid data length parameter.
If you would know how many bytes passed by in_someData why would you need in_data_length at all?
Actually, you can only check in_someData for NULL and in_data_length for positive value. Then return some error code if needed. If a user passed some garbage to your function, this problem is obviously not yours.
In C++, the magic word you're looking for is "exception". That gives you a method to tell the caller something went wrong. You'll end up with code something like
int
doStuff(unsigned char * inSomeData, int inDataLength) throws Exception {
// do a test
if(inDataLength == 0)
throw new Exception("Length can't be 0");
// only gets here if it passed the test
// do other good stuff
return theResult;
}
Now, there's another problem with your specific example, because there's no universal way in C or C++ to tell how long an array of primitives really is. It's all just bits, with inSomeData being the address of the first bits. Strings are a special case, because there's a general convention that a zero byte ends a string, but you can't depend on that for binary data -- a zero byte is just a zero byte.
Update
This has currently picked up some downvotes, apparently by people misled by the comment that exception specifications had been deprecated. As I noted in a comment below, this isn't actually true -- while the specification will be deprecated in C++11, it's still part of the language now, so unless questioner is a time traveler writing in 2014, the throws clause is still the correct way to write it in C++.
Also note that the original questioner says "I want to make it so that the user will know what happened, should he/she feeds [sic] invalid data in and the library crashes." Thus the question is not just what can I do to validate the input data (answer: not much unless you know more about the inputs than was stated), but then how do I tell the caller they screwed up? And the answer to that is "use the exception mechanism" which has certainly not been deprecated.