

GCC Non-bugs - chris_wot
http://gcc.gnu.org/bugs/#nonbugs

======
zamalek
> Casting does not work as expected when optimization is turned on.

> This is often caused by a violation of aliasing rules, which are part of the
> ISO C standard. These rules say that a program is invalid if you try to
> access a variable through a pointer of an incompatible type.

Regarding this, is this what reinterpret_cast was at least partially designed
for?

~~~
pjmlp
Kind of, casts in C++ were designed to be on your face, to call out that you
are doing something unsafe.

reinterpret_cast is meant to be really unsafe, to meant that in this type of
casts the compiler will blindly do it, whereas the other *_cast there is still
some type validation involved.

~~~
zamalek
Thanks for the clarification. So this doesn't signal to the compiler that it
shouldn't optimize the aliased variables?

 _Reason I ask and not test is that it seems that VC++ does not take advantage
of this undefined behavior and the sample code always works 'as expected'._

~~~
pjmlp
This type of optimization is very compiler specific and can even change
between versions of the same compiler.

Actually this is the big difference between standard defined languages and
those that rely on a single implementation.

There is nothing to rely upon if it isn't defined in the standard as such.

------
shortstuffsushi
I know this is a problem with many programming languages, but why is there not
a standard way to _precisely_ represent decimal numbers? I understand the
difficulty representing them in binary (well, kind of -- it's been a while
since I read about it), but it seems like knowing this, a better solution
would be found. Why is this accepted and standard behavior?

~~~
McKayDavis
Are you familiar with the IEEE 754-2008 specification of decimal floating
point format?

From Wikipedia's entry on decimal64[1]: "It is intended for applications where
it is necessary to emulate decimal rounding exactly, such as financial and tax
computations."

[1] [http://en.wikipedia.org/wiki/Decimal64_floating-
point_format](http://en.wikipedia.org/wiki/Decimal64_floating-point_format)

~~~
shortstuffsushi
No, I was not. I'm assuming that the standard double or float do not conform
to this spec, though, right?

------
andrewchambers
Something I found yesterday:

static char * s = * &"hello";

This should not compile, clang refuses it, and it is not part of the C
standard. GCC accepts it, but is it worth even submitting a bug report?

~~~
plorkyeran
Clang 3.5 compiles that for me without warnings even with -Weverything. String
literals in C (but not C++) aren't const for legacy reasons despite not being
modifiable.

~~~
andrewchambers
Sorry, I made a mistake. I think it is:

static char s[] = * &"foo";

The c standard says char array initializers are either a string, or a string
surrounded by optional '{}' .

~~~
plorkyeran
-pedantic gives "warning: array initialized from parenthesized string constant" for that, so I'm guessing it's an unintended consequence of a nonstandard extension. Might be worth reporting since at the minimum the warning is wrong.

------
markrages
In my embedded development, I have trained myself to use unions instead of
type-punned-pointer casts to access one data type as another.

This document says this is a GCC-specific extension. Is this true? Or is it
one of those things that's not standardized, but the compiler vendors all do
it anyway?

~~~
oshepherd
Type punning by pointer is explicitly UB per the standard.

Type punning by union is implementation defined behavior. Everyone fortunately
defines it to Do The Right Thing (TM).

The truly standard supported way to type pun is by memcpy

float f = ...; int x; memcpy(&x, &f, sizeof x);

~~~
jakobegger
Yes. Use memcpy if you need to do this! This is especially important when
you're on a platform that requires aligned pointers. For example, the
following code will crash on ARM

    
    
        char bytes[5] = {0};
        float flt = *(float*)&(bytes[1]);
    

Using memcpy works on any platform with 4 byte floats:

    
    
        char bytes[5] = {0};
        float flt;
        memcpy(&flt, &(bytes[1]), 4);

~~~
markrages
But the union won't crash either (the compiler will keep it aligned), the
conversion compiles to no-op, and doesn't waste memory.

Embedded targets are always memory-constrained. If they aren't, you are
wasting money on hardware.

~~~
jakobegger
I was thinking about the case when you get unaligned data (eg you are reading
from a file or from the network). Then you need to copy the data anyway.

------
webreac
"Most C++ compilers (G++ included) do not yet implement export". For me, non
compliance with such an old spec is a bug.

~~~
X-Istence
There is a single C++ compiler that supports export. Out of all the C++
compilers, only a single one supports it. Mainly because it is such a HUGE
pain in the ass to write support for.

See this paper as to why it was removed from the spec: [http://www.open-
std.org/jtc1/sc22/wg21/docs/papers/2003/n142...](http://www.open-
std.org/jtc1/sc22/wg21/docs/papers/2003/n1426.pdf)

~~~
andrewchambers
Those guys had serious dedication to essentially waste 3 years implementing
it, just to say how useless it is.

~~~
Retra
"John Spicer notes: “Any program written using export can be rearranged
trivially into a program that doesn’t use export.”"

This makes me wonder why they couldn't have implemented this rearrangement as
export...

~~~
andrewchambers
Probably trivially with some human judgment.

