Re: Why is this code valid C++?
From: Jack Klein (jackklein_at_spamcop.net)
Date: 02/11/05
- Next message: GTO: "Re: Hi, Python v.s. C++, which is better?"
- Previous message: Jerry Krinock: ""Reconstructing" (Calling the constructor again)"
- In reply to: Victor Bazarov: "Re: Why is this code valid C++?"
- Next in thread: Victor Bazarov: "Re: Why is this code valid C++?"
- Reply: Victor Bazarov: "Re: Why is this code valid C++?"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Thu, 10 Feb 2005 23:17:02 -0600
On Thu, 10 Feb 2005 17:38:13 -0500, Victor Bazarov
<v.Abazarov@comAcast.net> wrote in comp.lang.c++:
> James Aguilar wrote:
> > Someone showed me something today that I didn't understand. This doesn't
> > seem like it should be valid C++. Specifically, I don't understand how the
> > commas are accepted after the function 'fprintf'. What effect do they have
> > in those parenthesis?
>
> 'exit(0)' is executed. 1 is just for syntactic and semantic correctness,
> since the right operand of || has to have a value and 'exit' doesn't
> return any.
>
> >
> > I understand how the or is useful and why never to do it, I'm really just
> > asking about that construction "(fprintf(stderr, "Can't open file.\n"),
> > exit(0), 1))".
> >
> > ---- CODE ----
> >
> > #include <stdlib.h>
> > #include <stdio.h>
> >
> > int main()
> > {
> > FILE *fp = (FILE *) (fopen("file","r") ||
> > (fprintf(stderr, "Can't open file.\n"), exit(0), 1));
> > return 0;
> > }
> >
> > ---- /CODE ----
>
> It's not valid C++. It's valid C90. But it's very close to being valid
> C++, though.
>
> The || operator causes the evaluation of the left operand. If the result
> of that evaluation is not zero (and in this case if 'fopen' returns a non-
> null pointer), the evaluation stops. HOWEVER, 'fp' may simply get a wrong
> value. Once the left side of || is non-zero, it _may_ be converted (and
> should be converted) to a bool value, which is 'true'. After that the
> same 'true' is cast back to (FILE*), which causes undefined behaviour.
No, it does not, this conversion is well defined.
3.9.1 Fundamental types P7: "Types bool, char, wchar_t, and the signed
and unsigned integer types are collectively called integral types."
5.2.10 Reinterpret cast P5: "A value of integral type or enumeration
type can be explicitly converted to a pointer."
And 5.4 Explicit type conversion (cast notation) makes it quite clear
that the C-style case can perform any valid conversions that any C++
cast can.
So the explicit cast of the value 1 or true is valid in either C or
C++, regardless of whether that value has the type bool (C++), int
(C90), or _bool (C99).
The C++ standard in 5.2.10 P5 includes the clause "mappings between
pointers and integers are otherwise implementation-defined.", while I
prefer the C standard's stronger disclaimer:
========
An integer may be converted to any pointer type. Except as previously
specified, the result is implementation-defined, might not be
correctly aligned, might not point to an entity of the referenced
type, and might be a trap representation.
========
In any case, the conversion to pointer is not undefined, but any
attempt to dereference the resulting pointer most certainly is.
-- Jack Klein Home: http://JK-Technology.Com FAQs for comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html comp.lang.c++ http://www.parashift.com/c++-faq-lite/ alt.comp.lang.learn.c-c++ http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
- Next message: GTO: "Re: Hi, Python v.s. C++, which is better?"
- Previous message: Jerry Krinock: ""Reconstructing" (Calling the constructor again)"
- In reply to: Victor Bazarov: "Re: Why is this code valid C++?"
- Next in thread: Victor Bazarov: "Re: Why is this code valid C++?"
- Reply: Victor Bazarov: "Re: Why is this code valid C++?"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|