public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* calling exit in response to an error shouldn't be an error...
@ 2019-06-09 21:21 L A Walsh
  2019-06-09 21:52 ` Zan Lynx
  0 siblings, 1 reply; 5+ messages in thread
From: L A Walsh @ 2019-06-09 21:21 UTC (permalink / raw)
  To: gcc

If I have a function returning NULL on error (including EOF).

So the program calls exit if the function doesn't return
a non-zero value (func() || exit(1)).

I have:

--/tmp/ex.c--

main() { char * buf[512];
    while (gets(buf) || exit(0)) puts(buf);
}

-- compile w/:
gcc -fpermissive --no-warnings  -o /tmp/ex /tmp/ex.c

Got:
/tmp/ex.c: In function ‘main’:
/tmp/ex.c:2:22: error: void value not ignored as it ought to be
  while (gets(buf) || exit(0) ) puts(buf);
                      ^~~~~~~

I understand that the while is testing the value of exit
"when it returns", but since it doesn't, why flag an error
(if exit is part of C-standard?) but *especially*, why
not a warning, like a type mismatch or such?


But this:

--/tmp/ex2.c--

main(){ char * buf[512];
  while (1) {
    fgets(buf) || exit(1);
    fputs(buf);
  }
}

---compile + output:
> gcc -fpermissive --no-warnings  -o /tmp/ex2 /tmp/ex2.c
/tmp/ex2.c: In function ‘main’:
/tmp/ex2.c:4:18: error: void value not ignored as it ought to be
    fgets(buf) || exit(1);
                  ^~~~~~~

Ultra confusing -- how is exit value used?  Isn't it thrown away?




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: calling exit in response to an error shouldn't be an error...
  2019-06-09 21:21 calling exit in response to an error shouldn't be an error L A Walsh
@ 2019-06-09 21:52 ` Zan Lynx
  2019-06-10 21:54   ` L A Walsh
  2019-06-10 22:03   ` P.S. - " L A Walsh
  0 siblings, 2 replies; 5+ messages in thread
From: Zan Lynx @ 2019-06-09 21:52 UTC (permalink / raw)
  To: gcc

I am not a GCC developer, just a regular user of C. But I have some 
comments below:

On 6/9/2019 3:21 PM, L A Walsh wrote:
> If I have a function returning NULL on error (including EOF).
> 
> So the program calls exit if the function doesn't return
> a non-zero value (func() || exit(1)).
> 
> I have:
> 
> --/tmp/ex.c--
> 
> main() { char * buf[512];
>      while (gets(buf) || exit(0)) puts(buf);
> }
> 
> -- compile w/:
> gcc -fpermissive --no-warnings  -o /tmp/ex /tmp/ex.c
> 
> Got:
> /tmp/ex.c: In function ‘main’:
> /tmp/ex.c:2:22: error: void value not ignored as it ought to be
>    while (gets(buf) || exit(0) ) puts(buf);
>                        ^~~~~~~
> 
> I understand that the while is testing the value of exit
> "when it returns", but since it doesn't, why flag an error
> (if exit is part of C-standard?) but *especially*, why
> not a warning, like a type mismatch or such?i

There is a slight misunderstanding of operators here. This is not while 
testing the value of exit(0). This is the "||" operator. It needs a 
value on *both* sides of || so it can evaluate them both and return a 
boolean result. Your code has no value on the right-hand side so it's 
meaningless.

> 
> 
> But this:
> 
> --/tmp/ex2.c--
> 
> main(){ char * buf[512];
>    while (1) {
>      fgets(buf) || exit(1);
>      fputs(buf);
>    }
> }
> 
> ---compile + output:
>> gcc -fpermissive --no-warnings  -o /tmp/ex2 /tmp/ex2.c
> /tmp/ex2.c: In function ‘main’:
> /tmp/ex2.c:4:18: error: void value not ignored as it ought to be
>      fgets(buf) || exit(1);
>                    ^~~~~~~
> 
> Ultra confusing -- how is exit value used?  Isn't it thrown away?

Same problem here.

I haven't tested it but you might be able to make this work with a comma 
operator like "while (gets(buf) || (exit(0), 1)) puts(buf);"

Oh, and "gets" is no longer a function. It's not just deprecated. It's 
*gone*.

-- 
                 Knowledge is Power -- Power Corrupts
                         Study Hard -- Be Evil

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: calling exit in response to an error shouldn't be an error...
  2019-06-09 21:52 ` Zan Lynx
@ 2019-06-10 21:54   ` L A Walsh
  2019-06-10 22:00     ` Jonathan Wakely
  2019-06-10 22:03   ` P.S. - " L A Walsh
  1 sibling, 1 reply; 5+ messages in thread
From: L A Walsh @ 2019-06-10 21:54 UTC (permalink / raw)
  To: Zan Lynx; +Cc: gcc

On 2019/06/09 14:52, Zan Lynx wrote:
> I am not a GCC developer, just a regular user of C. But I have some 
> comments below:
>
> On 6/9/2019 3:21 PM, L A Walsh wrote:
>   
>> If I have a function returning NULL on error (including EOF).
>>
>> So the program calls exit if the function doesn't return
>> a non-zero value (func() || exit(1)).
>>
>> I have:
>>
>> --/tmp/ex.c--
>>
>> main() { char * buf[512];
>>      while (gets(buf) || exit(0)) puts(buf);
>> }
>>
>> -- compile w/:
>> gcc -fpermissive --no-warnings  -o /tmp/ex /tmp/ex.c
>>
>> Got:
>> /tmp/ex.c: In function ‘main’:
>> /tmp/ex.c:2:22: error: void value not ignored as it ought to be
>>    while (gets(buf) || exit(0) ) puts(buf);
>>                        ^~~~~~~
>>
>> I understand that the while is testing the value of exit
>> "when it returns", but since it doesn't, why flag an error
>> (if exit is part of C-standard?) but *especially*, why
>> not a warning, like a type mismatch or such?
>>     
>
> There is a slight misunderstanding of operators here. This is not while 
> testing the value of exit(0). This is the "||" operator. It needs a 
> value on *both* sides of || so it can evaluate them both and return a 
> boolean result. Your code has no value on the right-hand side so it's 
> meaningless.
>   
----
    Um, but '||' and '&&' provide short circuiting.  So in the case where
the first function is true, the 2nd won't be called.  If the 2nd is called
it is guaranteed by the C11(17) standard not to return, so there can never
be a need for a return value in C11, as the program will terminate before
the value could be needed.
>   
>> But this:
>>
>> --/tmp/ex2.c--
>>
>> main(){ char * buf[512];
>>    while (1) {
>>      fgets(buf) || exit(1);
>>      fputs(buf);
>>    }
>> }
>>
>> ---compile + output:
>>     
>>> gcc -fpermissive --no-warnings  -o /tmp/ex2 /tmp/ex2.c
>>>       
>> /tmp/ex2.c: In function ‘main’:
>> /tmp/ex2.c:4:18: error: void value not ignored as it ought to be
>>      fgets(buf) || exit(1);
>>                    ^~~~~~~
>>
>> Ultra confusing -- how is exit value used?  Isn't it thrown away?
>>     
>
> Same problem here.
>   
----
    But the result isn't needed and is clearly never used even if
'exit' didn't actually terminate the program.  I.e. if the user wrote:
"1 || 2;"

    I can't see a current C11 compiler even emitting any code for such, but
I could see it emit a warning for something that would likely be a
user-error even if it was permitted by the language.

> I haven't tested it but you might be able to make this work with a comma 
> operator like "while (gets(buf) || (exit(0), 1)) puts(buf);"
>
> Oh, and "gets" is no longer a function. It's not just deprecated. It's 
> *gone*.
>   
---
    Still works though. In gcc 8.2.1 (which is said to be C18
compliant).  "gets" was said to be left in so that older programs
wouldn't suddenly fail over
something so widely used in examples (even though unsafe).

    I did contemplate including an equally safe workaround or at least a
getsn(buff,len), but resisted both urges as it wasn't the point of the
report.

   

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: calling exit in response to an error shouldn't be an error...
  2019-06-10 21:54   ` L A Walsh
@ 2019-06-10 22:00     ` Jonathan Wakely
  0 siblings, 0 replies; 5+ messages in thread
From: Jonathan Wakely @ 2019-06-10 22:00 UTC (permalink / raw)
  To: L A Walsh; +Cc: Zan Lynx, gcc

On Mon, 10 Jun 2019 at 22:54, L A Walsh <gcc@tlinx.org> wrote:
>
> On 2019/06/09 14:52, Zan Lynx wrote:
> > I am not a GCC developer, just a regular user of C. But I have some
> > comments below:
> >
> > On 6/9/2019 3:21 PM, L A Walsh wrote:
> >
> >> If I have a function returning NULL on error (including EOF).
> >>
> >> So the program calls exit if the function doesn't return
> >> a non-zero value (func() || exit(1)).
> >>
> >> I have:
> >>
> >> --/tmp/ex.c--
> >>
> >> main() { char * buf[512];
> >>      while (gets(buf) || exit(0)) puts(buf);
> >> }
> >>
> >> -- compile w/:
> >> gcc -fpermissive --no-warnings  -o /tmp/ex /tmp/ex.c
> >>
> >> Got:
> >> /tmp/ex.c: In function ‘main’:
> >> /tmp/ex.c:2:22: error: void value not ignored as it ought to be
> >>    while (gets(buf) || exit(0) ) puts(buf);
> >>                        ^~~~~~~
> >>
> >> I understand that the while is testing the value of exit
> >> "when it returns", but since it doesn't, why flag an error
> >> (if exit is part of C-standard?) but *especially*, why
> >> not a warning, like a type mismatch or such?
> >>
> >
> > There is a slight misunderstanding of operators here. This is not while
> > testing the value of exit(0). This is the "||" operator. It needs a
> > value on *both* sides of || so it can evaluate them both and return a
> > boolean result. Your code has no value on the right-hand side so it's
> > meaningless.
> >
> ----
>     Um, but '||' and '&&' provide short circuiting.  So in the case where

That's irrelevant (but then this whole question is irrelevant to this
mailing list and really belongs somewhere dedicated to C programming).

> the first function is true, the 2nd won't be called.  If the 2nd is called
> it is guaranteed by the C11(17) standard not to return, so there can never
> be a need for a return value in C11, as the program will terminate before
> the value could be needed.

But C is still a statically typed language. The || operator requires
two operands with scalar type, so void is not allowed.

The fact that exit doesn't return is not part of the type system. The
return type of exit is void, and so you can't use it where void is not
allowed.


>     Still works though. In gcc 8.2.1 (which is said to be C18
> compliant).

gets is provide by your C library, not GCC.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* P.S. - Re: calling exit in response to an error shouldn't be an error...
  2019-06-09 21:52 ` Zan Lynx
  2019-06-10 21:54   ` L A Walsh
@ 2019-06-10 22:03   ` L A Walsh
  1 sibling, 0 replies; 5+ messages in thread
From: L A Walsh @ 2019-06-10 22:03 UTC (permalink / raw)
  To: Zan Lynx; +Cc: gcc

On 2019/06/09 14:52, Zan Lynx wrote:
> I haven't tested it but you might be able to make this work with a comma
> operator like "while (gets(buf) || (exit(0), 1)) puts(buf);"
>   
yes, I also tried that to verify whether or not I needed a work-around
for gets, though using

"xit(int s){ exit(s);}"

was easier to toggle in and out of the test program by removing or
adding the 'e' before 'exit' calls in the program.

Also simply adding:

extern int exit(int);

was another way to *make* it work, if that was what I needed to do
in trying to understand and verify as working this 29 year-old,
'simple-shell', obfuscation:

   https://www.ioccc.org/1990/tbr.hint

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2019-06-10 22:03 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-09 21:21 calling exit in response to an error shouldn't be an error L A Walsh
2019-06-09 21:52 ` Zan Lynx
2019-06-10 21:54   ` L A Walsh
2019-06-10 22:00     ` Jonathan Wakely
2019-06-10 22:03   ` P.S. - " L A Walsh

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).