From mboxrd@z Thu Jan 1 00:00:00 1970 MIME-Version: 1.0 References: <20180801072134.DEB31156E400@mail.bitblocks.com> In-Reply-To: <20180801072134.DEB31156E400@mail.bitblocks.com> From: Charles Forsyth Date: Thu, 2 Aug 2018 00:35:47 +0100 Message-ID: To: Fans of the OS Plan 9 from Bell Labs <9fans@9fans.net> Content-Type: multipart/alternative; boundary="0000000000001f292f05726828c2" Subject: Re: [9fans] A compiler bug Topicbox-Message-UUID: d9967d12-ead9-11e9-9d60-3106f5b1d025 --0000000000001f292f05726828c2 Content-Type: text/plain; charset="UTF-8" "6.6 Constant expressions" doesn't allow a cast from a non-arithmetic type to an arithmetic one generally, and a cast in an address constant can only cast from an integer constant to a pointer type (eg, char *reg = (char*)0x123450); the one example with 8c escaped with a warning ("initialize pointer to an integer") because of some 8c x86-specific folding that makes the expression acceptable. even so, the format and intention of the example seems practical (with the correct cast to uintptr) and "An implementation may accept other forms of constant expressions". it should be fairly easy to add as an extension with consistent handling across ?c. On Wed, 1 Aug 2018 at 08:22, Bakul Shah wrote: > Consider: > > % cat x.c > #include > uintptr foo[3]; > uintptr bar=&foo[2]; > > % 8c -c x.c # this works. > % 5c -c x.c # this fails > x.c:3 initializer is not a constant: bar > > If I change the last line to > > uintptr* bar=&foo[2]; > > Both compilers compile it fine. But if I change the last line > to > > uintptr bar=(uintptr)&foo[2]; > > both compilers fail. Note that the last two examples are > type correct. > > uintptr is the same size as int* so there should be no runtime > cost and we already know from the second example that &foo[2] > is a link time constant. > > Similar code to the last two examples compiles on gcc/clang. > > This seems like a compiler bug. > > --0000000000001f292f05726828c2 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
"6.6 Constant expressions" doesn't allow a c= ast from a non-arithmetic type to an arithmetic one generally, and a castin an address constant can only cast from an integer constant to a point= er type (eg, char *reg =3D (char*)0x123450);

the o= ne example with 8c escaped with a warning ("initialize pointer to an i= nteger") because of some 8c x86-specific folding that makes the expres= sion acceptable.

even so, the format and intention of the example seems practical (with= the correct cast to uintptr) and "An implementation may accept other = forms of constant expressions".
it should b= e fairly easy to add as an extension with consistent handling across ?c.


On Wed, 1 Aug 2018 at 08:22, Bakul Sh= ah <bakul@bitblocks.com> w= rote:
Consider:

% cat x.c
#include <u.h>
uintptr foo[3];
uintptr bar=3D&foo[2];

% 8c -c x.c=C2=A0 =C2=A0 =C2=A0# this works.
% 5c -c x.c=C2=A0 =C2=A0 =C2=A0# this fails
x.c:3 initializer is not a constant: bar

If I change the last line to

uintptr* bar=3D&foo[2];

Both compilers compile it fine. But if I change the last line
to

uintptr bar=3D(uintptr)&foo[2];

both compilers fail. Note that the last two examples are
type correct.

uintptr is the same size as int* so there should be no runtime
cost and we already know from the second example that &foo[2]
is a link time constant.

Similar code to the last two examples compiles on gcc/clang.

This seems like a compiler bug.

--0000000000001f292f05726828c2--