LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   return -1 of main but get exit code is 255? why? pls advise. (https://www.linuxquestions.org/questions/linux-newbie-8/return-1-of-main-but-get-exit-code-is-255-why-pls-advise-888883/)

youxi600 06-28-2011 09:52 PM

return -1 of main but get exit code is 255? why? pls advise.
 
I learn C++ reading the <C++ primer 4th>, question1.2 let me test if return -1 how the compiler handle this exit code.
and in gcc (GCC) 4.1.1 20070105 (Red Hat 4.1.1-52), I get this show:

[youxi600@Arthas C++ Primer]$ cat q1_2.cpp
int main()
{
return -1;
}
[youxi600@Arthas C++ Primer]$ gcc q1_2.cpp -o q1_2
[youxi600@Arthas C++ Primer]$ ./q1_2
[youxi600@Arthas C++ Primer]$ echo $?
255
[youxi600@Arthas C++ Primer]$
anyone can give me an advise? Many thanks!

paulsm4 06-28-2011 10:02 PM

Because 255 == 0xff == -1 for an 8-bit signed value :)

rknichols 06-28-2011 10:12 PM

Yes, the exit status is effectively an unsigned char. The relevant definition in /usr/include/bits/waitstatus.h is:

Code:

#define        __WEXITSTATUS(status)        (((status) & 0xff00) >> 8)

youxi600 06-28-2011 10:20 PM

Quote:

Originally Posted by paulsm4 (Post 4398631)
Because 255 == 0xff == -1 for an 8-bit signed value :)

But my main function return type is "int" not an 8-bit signed. Confused!

youxi600 06-28-2011 10:21 PM

Quote:

Originally Posted by rknichols (Post 4398643)
Yes, the exit status is effectively an unsigned char. The relevant definition in /usr/include/bits/waitstatus.h is:

Code:

#define        __WEXITSTATUS(status)        (((status) & 0xff00) >> 8)

why? I have assume it's return type to "int".

grail 06-28-2011 11:14 PM

So I will defer to paulsm4 for the C / C++ side as he is very experienced in these matters, but I think maybe you might be mixing apples and oranges.
Irrelevant of what is occurring within your code, the exit status in the shell can ONLY be between 0 and 255. So if you create a one line bash script:
Code:

#!/bin/bash

exit -1

This will give you the same result when looking at the exit code using $?. For that matter if you change it to -2 it will be 254 as it treats it like
a loop once past zero.

I am sure there is official information that others can give, but I just wanted to point out that the shell is the one here doing the translation and not your program
(even though it may be as well)

chrism01 06-29-2011 01:16 AM

Contrary to appearances, 'int' is not really a basic type; more accurately 'int' defaults to come combination of 8, 16, 32, 64 (or larger multiples of 2) bit, signed or unsigned.
Check your compiler manual & eg http://www.dummies.com/how-to/conten...bers-in-c.html

youxi600 06-29-2011 01:35 AM

Quote:

Originally Posted by grail (Post 4398666)
So I will defer to paulsm4 for the C / C++ side as he is very experienced in these matters, but I think maybe you might be mixing apples and oranges.
Irrelevant of what is occurring within your code, the exit status in the shell can ONLY be between 0 and 255. So if you create a one line bash script:
Code:

#!/bin/bash

exit -1

This will give you the same result when looking at the exit code using $?. For that matter if you change it to -2 it will be 254 as it treats it like
a loop once past zero.

I am sure there is official information that others can give, but I just wanted to point out that the shell is the one here doing the translation and not your program
(even though it may be as well)

Thanks.
I think I can get your means. No matter which type the main returned, the "echo $?" shell command just ONLY get a unsigned 8-bit exit code.
And I find one book may be help explain this viewpoint.

The New Kornshell Command and Programming Language by Morris Bolsky and David Korn says:
Quote:
0 Normal exit.
1-125 Failure.
126 A command was found but cannot be executed.
127 A command could not be found.
128-255 Failure.
256 and above A command has exited because of reciept of a signal.
Version: With the 11/16/88 version of ksh, 129-160 indicated that a command had exited because of a signal....A command that could not be found or could not execute had a return value of 1.

youxi600 06-29-2011 01:38 AM

Quote:

Originally Posted by chrism01 (Post 4398750)
Contrary to appearances, 'int' is not really a basic type; more accurately 'int' defaults to come combination of 8, 16, 32, 64 (or larger multiples of 2) bit, signed or unsigned.
Check your compiler manual & eg http://www.dummies.com/how-to/conten...bers-in-c.html

Thanks. I will check it.

MTK358 06-29-2011 07:55 AM

Actually, the unsigned 8-bit exit code limitation is part of the kernel, not the shell.

rknichols 06-29-2011 10:49 AM

The only access to that "int" from main() is the value that is returned when the parent performs a wait() system call, which returns a 16-bit quantity with two 8-bit fields. One field is the low-order 8 bits of the exit status; the other field is the terminating signal. That's all that is available to any program.

MTK358 06-29-2011 10:57 AM

Quote:

Originally Posted by rknichols (Post 4399231)
The only access to that "int" from main() is the value that is returned when the parent performs a wait() system call, which returns a 16-bit quantity with two 8-bit fields. One field is the low-order 8 bits of the exit status; the other field is the terminating signal. That's all that is available to any program.

Does that mean that my above post is wrong?

Does the other field with the terminating signal have anything to do with main()'s return value?

chrism01 06-29-2011 07:41 PM

I believe it's a bit of both.
Inside C, 'int' could be almost anything (see my post #7) if its setup to do so, but once you pass the value back to the shell, it can only represent/present an 8 bit value. Not sure if that's the shell or the kernel.
If it was the kernel, in theory it should be able to use anything up to the bit size of the kernel eg 32 or 64.
I suspect( and could be wrong) that it's a shell limit.

Answers on a postcard pls ... :)

rknichols 06-30-2011 02:14 PM

Quote:

Originally Posted by MTK358 (Post 4399240)
Does that mean that my above post is wrong?

Does the other field with the terminating signal have anything to do with main()'s return value?

No, it's just a signal number, and would be zero for a process that exited normally.
Code:

#define __WTERMSIG(status)      ((status) & 0x7f)
#define __WIFEXITED(status)    (__WTERMSIG(status) == 0)

It appears that the kernel might actually store the whole integer within the task_struct structure. It's just that the wait() system call returns only the low-order 8 bits of the exit code plus an 8-bit signal number all packed into the low order 16 bits of an integer. The macros for testing and extracting those fields are described in the wait(2) manpage and defined in /usr/include/bits/waitstatus.h.

Looking at that manpage, I see a slightly newer system call, waitid(), that looks like it might return the entire integer in the si_status member of the siginfo_t structure. For a C (or C++) program, it might be worth taking a look at that if you really need to see more than those low 8 bits of the exit status. I've never used waitid(2), so I'm not sure what is really returned.


All times are GMT -5. The time now is 10:59 AM.