From: James Van Buskirk on
"James Van Buskirk" <not_valid(a)comcast.net> wrote in message
news:hq4jdl$inv$1(a)news.eternal-september.org...

> incorrect. I can't seem to find that thread today via Google; in fact
> I can't get Google to find posts containing the word "end" in
> comp.lang.fortran today, maybe you'll have better luck than me.

OK, it seems to be:

http://groups.google.com/group/comp.lang.fortran/browse_frm/thread/acc43a6439ea81e7/6a5bd9eae429fe96?hl=en&q=_Bool+group:comp.lang.fortran

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


From: Tobias Burnus on
On 04/14/2010 04:27 PM, James Van Buskirk wrote:
[ GCC 4.5.0]

> There is also a new section in the manual: 5.2 Internal representation
> of logical variables that contains information that, according to my
> experience from the last time I tilted at this particular windmill, is
> incorrect.

The section is
http://gcc.gnu.org/onlinedocs/gfortran/Internal-representation-of-LOGICAL-variables.html

Can you elaborate why you think that this information is wrong?

It was added because of interoperability issues with a compiler. One can
increase the performance for logical variables if one only operates with
the highest or lowest bit. GCC applies this optimization at least for
higher optimization levels using either in Fortran LOGICAL or in C the
_Bool datatype.

Well, gfortran uses 1 for .true. and 0 for .false. for all kinds of
LOGICAL including c_Bool.

The other compiler uses -1 for .true. and 0 for false. The problem is
applying a .NOT. to the Boolean returned from the other compiler:
..NOT.(-1) is "-2" in GCC and "0" in the other compiler. GCC regards -1
and -2 as .true., the other compiler 0 and -2 as .false. Both comppilers
handle .not.1 correctly (false) though the value is different (0 [gcc]
vs. -2).

So far, I do not see any misinformation in the section and I see a real
interoperability problem, though I would claim that GCC's result for
C_Bool is arguably more compatible with C99's 6.3.1.2: "When any scalar
value is converted to _Bool, the result is 0 if the value compares equal
to 0; otherwise, the result is 1."

Thus, I do not see what besides adding the notice to the manual could
have been done. And, especially, I do not see how removing this section
would help.

Tobias
From: James Van Buskirk on
"Tobias Burnus" <burnus(a)net-b.de> wrote in message
news:4BC5D572.6020609(a)net-b.de...

> So far, I do not see any misinformation in the section and I see a real
> interoperability problem, though I would claim that GCC's result for
> C_Bool is arguably more compatible with C99's 6.3.1.2: "When any scalar
> value is converted to _Bool, the result is 0 if the value compares equal
> to 0; otherwise, the result is 1."

Values may be placed in a C _Bool without conversion and that's where
the fun begins. C defines 0 false and everything else true, so when a
C _Bool gets somehow set to any non-idempotent value, as by casting
pointers or reading from stream I/O (whatever the C name for it is) you
get a value that evaluates as true, but is otherwise unexpected.

This situation could be fixed in C99 in isolation by considering high
bits to be unused, but I was informed in that thread that C99 _Bool is
intended to be an interoperability feature with C++, and I can't make
heads nor tails of the C++ standard document, so I don't know whether
that fix could be applied to that language.

If it could, that would be great, as the change could then propagate
from g++ bool to gcc _Bool to gfortran LOGICAL(C_BOOL) and then to
all LOGICAL kinds, but as matters currently stand gfortran has no
kind compatible with C99 _Bool and should return a negative value
for C_BOOL rather than trying to match the broken C _Bool semantics.

> Thus, I do not see what besides adding the notice to the manual could
> have been done. And, especially, I do not see how removing this section
> would help.

The thread is:
http://groups.google.com/group/comp.lang.fortran/browse_frm/thread/acc43a6439ea81e7/6a5bd9eae429fe96

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


From: JB on
On 2010-04-14, James Van Buskirk <not_valid(a)comcast.net> wrote:
> "Tobias Burnus" <burnus(a)net-b.de> wrote in message
> news:4BC5D572.6020609(a)net-b.de...
>
>> So far, I do not see any misinformation in the section and I see a real
>> interoperability problem, though I would claim that GCC's result for
>> C_Bool is arguably more compatible with C99's 6.3.1.2: "When any scalar
>> value is converted to _Bool, the result is 0 if the value compares equal
>> to 0; otherwise, the result is 1."
>
> Values may be placed in a C _Bool without conversion and that's where
> the fun begins.

From the perspective of the C standard, the above is where undefined
behavior begins, as is most cases of type punning.

> C defines 0 false and everything else true, so when a
> C _Bool gets somehow set to any non-idempotent value, as by casting
> pointers or reading from stream I/O (whatever the C name for it is) you
> get a value that evaluates as true, but is otherwise unexpected.

C99 _Bool is an unsigned integer variable which can hold only the
values 0 or 1. Any other bit pattern is a trap representation (i.e. a
bit pattern that, if accessed, results in undefined behavior).

As circumstantial evidence of this, at least on x86 gcc compiles the
simple C function

_Bool neg(_Bool b)
{
return !b;
}

such that the negation operator (!, same as .not. in Fortran) is a
bitwise XOR of the variable and the constant 1. Thus any other bit
pattern than the integers 0 or 1 results in nonsense.

As an aside, if you repeat the above experiment with gfortran LOGICAL
(any logical kind, including C_BOOL) and g++ bool, it results in the
same bitwise XOR.

> This situation could be fixed in C99 in isolation by considering high
> bits to be unused, but I was informed in that thread that C99 _Bool is
> intended to be an interoperability feature with C++, and I can't make
> heads nor tails of the C++ standard document, so I don't know whether
> that fix could be applied to that language.

IIRC in C++ the internal representation of the bool type is undefined,
just like Fortran. Due to bool's converting to 0 or 1,

"An rvalue of type bool can be converted to an rvalue of type int, with
false becoming zero and true becoming one.",

I'd be surprised if there are any C++ compilers that do not represent
bool with the integer 1 for true and 0 for false. So perhaps C99 just
standardized existing practice by specifying the internal
representation?

> If it could, that would be great, as the change could then propagate
> from g++ bool to gcc _Bool to gfortran LOGICAL(C_BOOL) and then to
> all LOGICAL kinds

AFAICS, this is the situation today.


--
JB
From: James Van Buskirk on
"JB" <foo(a)bar.invalid> wrote in message
news:slrnhsc7ek.3kb.foo(a)kosh.hut.fi...

> C99 _Bool is an unsigned integer variable which can hold only the
> values 0 or 1. Any other bit pattern is a trap representation (i.e. a
> bit pattern that, if accessed, results in undefined behavior).

In the thread referred to earlier, the participants looked at the C99
standard and found no such assertion. Perhaps you are better at
finding a statement like this in the standard?

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end