* more compilation failures: -DSCM_DEBUG_TYPING_STRICTNESS=2
@ 2009-09-01 6:23 Ken Raeburn
2009-09-01 6:26 ` Ken Raeburn
2009-09-01 19:47 ` Ludovic Courtès
0 siblings, 2 replies; 16+ messages in thread
From: Ken Raeburn @ 2009-09-01 6:23 UTC (permalink / raw)
To: guile-devel
[[ Resending from an account I'm actually subscribed with. ]]
Compiling with SCM_DEBUG_TYPING_STRICTNESS=2 as discussed in __scm.h
causes SCM to be defined as a union type (though the comments say a
struct type), which enhances the type checking by making random
conversions and casts to and from pointer and integer types not work
without going through the correct conversion macros/functions.
Problem is, we're doing a lot of those.
It also means constant values for static initializers ("{ { BITS } }")
have a different form from run-time expressions generating certain
values ("scm_pack (BITS)" calls an inline function), and comparisons
can't be done with "==" and "!=". (In fact, tags.h already says "SCM
values can not be compared by using the operator ==", right above the
definition of scm_is_eq.)
Guess what we're also doing? :-)
And I haven't even tried compiling Ludovic's bdw-gc-static-alloc
branch yet, just master.
I can clean some of this up trivially -- SCM_PACK/SCM_UNPACK as
needed, change == to scm_is_eq. The initializers make it slightly
less trivial, and I can imagine different courses of action.
#1: We continue to not support static initialization. Move most of
the initializations in the library to the per-file init functions, and
for stuff like the ra_iproc tables in array-map.c we may want *one*
internal initializer macro (SCM_I_UNSPECIFIED_INIT or
SCM_I_UNDEFINED_INIT? maybe even something zero-valued) for filling in
slots in static structures without getting compiler warnings about
missing initializers.
#1a: Extend #1 later with whatever internal macros are needed to
provide the right initialization syntax for constructs used in bdw-gc-
static-alloc based on the STRICTNESS setting.
#1b: Try to supplement #1 with changes to SCM_PACK or SCM_MAKIFLAG to
make it not considered a compile-time constant even with STRICTNESS<2
and thus SCM_UNSPECIFIED, SCM_BOOL_F, etc are never suitable for
static initialization, catching this problem earlier in the future. I
believe a use of a comma expression will suffice, but finding a form
that doesn't generate compiler warnings and doesn't generate run-time
code could be tricky. (Though, it becomes easier if we require only no
performance impact when optimizing and with ... what, inline function
support? gcc?)
#1c: Try to supplement #1 by defaulting to STRICTNESS=2 on platforms
where the union is passed and returned the same way as the pointer or
integer in function calls, and where there isn't a significant
performance impact. Probably selected via cpp macros in __scm.h, since
an autoconf feature test would be difficult at best, and still
specific to the compiler used for building libguile and not the one
used to build the application. This helps us avoid the "==" and
random casting part of the problem better in the future. Mac OS X
(10.5, Intel) seems to use the same calling convention both ways in
one simple test, though I haven't tried performance testing.
#2: Drop STRICTNESS=2 support and really support static initialization
with the current macros.
#3: Keep STRICTNESS=2 support, and support static initialization, even
for application code, with a bunch of new macros.
Thoughts? My preference is for #1 now, and #1a/b/c when convenient or
needed.
Ken
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: more compilation failures: -DSCM_DEBUG_TYPING_STRICTNESS=2
2009-09-01 6:23 more compilation failures: -DSCM_DEBUG_TYPING_STRICTNESS=2 Ken Raeburn
@ 2009-09-01 6:26 ` Ken Raeburn
2009-09-16 19:20 ` Andy Wingo
2009-09-01 19:47 ` Ludovic Courtès
1 sibling, 1 reply; 16+ messages in thread
From: Ken Raeburn @ 2009-09-01 6:26 UTC (permalink / raw)
To: guile-devel
On Sep 1, 2009, at 02:23, Ken Raeburn wrote:
> I can clean some of this up trivially -- SCM_PACK/SCM_UNPACK as
> needed, change == to scm_is_eq. The initializers make it slightly
> less trivial, and I can imagine different courses of action.
Okay, not quite so trivial as I blithely asserted.
It looks like the eval code is going to be annoying too -- lots of
case labels that are constructed by making SCM values and then
extracting bits from them with ISYMNUM, which won't work with a
union. I'm thinking, maybe an enum or list of macros to define the
basic set of integers, and then apply SCM_MAKISYM to the enumerator
values, and then we can refer to the values symbolically without
extracting bits out of constructed SCM values?
The smob creation macros play fast and loose with types, and accept
anything that can be cast to scm_t_bits... which doesn't include union
types like SCM in this mode; extracting values is similarly messy.
I'm not sure that can be cleaned up without changing the API.
There are also bits that I suspect won't build cleanly if SCM is an
integer (STRICTNESS=0), too.
Ken
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: more compilation failures: -DSCM_DEBUG_TYPING_STRICTNESS=2
2009-09-01 6:26 ` Ken Raeburn
@ 2009-09-16 19:20 ` Andy Wingo
2009-11-18 5:52 ` Ken Raeburn
0 siblings, 1 reply; 16+ messages in thread
From: Andy Wingo @ 2009-09-16 19:20 UTC (permalink / raw)
To: Ken Raeburn; +Cc: guile-devel
On Tue 01 Sep 2009 08:26, Ken Raeburn <raeburn@raeburn.org> writes:
> On Sep 1, 2009, at 02:23, Ken Raeburn wrote:
>> I can clean some of this up trivially -- SCM_PACK/SCM_UNPACK as
>> needed, change == to scm_is_eq. The initializers make it slightly
>> less trivial, and I can imagine different courses of action.
>
> Okay, not quite so trivial as I blithely asserted.
>
> It looks like the eval code is going to be annoying too
All this will be gone within a month, hopefully. Further details to
come.
I don't see it as such a big problem to play "fast and loose" with
types, honestly... one day we'll have native compilation, and it's all
just words there.
Andy
--
http://wingolog.org/
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: more compilation failures: -DSCM_DEBUG_TYPING_STRICTNESS=2
2009-09-16 19:20 ` Andy Wingo
@ 2009-11-18 5:52 ` Ken Raeburn
2009-11-18 9:37 ` Ludovic Courtès
0 siblings, 1 reply; 16+ messages in thread
From: Ken Raeburn @ 2009-11-18 5:52 UTC (permalink / raw)
To: guile-devel
Picking up this thread again...
I've run some basic tests, and it looks like setting
SCM_DEBUG_TYPING_STRICTNESS to 0 (which causes SCM to be defined as an
integer type) also fails, though not quite as messily as setting it to
2.
On Sep 16, 2009, at 15:20, Andy Wingo wrote:
> I don't see it as such a big problem to play "fast and loose" with
> types, honestly... one day we'll have native compilation, and it's all
> just words there.
(Sorry, as a former compiler guy, I find my "portability" buttons
being pushed here....)
Words with what representation? Take a look at SCM2PTR and
PTR2SCM ... for the old Cray systems. As the comment above the
definition indicates, the machine has an unusual pointer
representation. Still compliant with the C spec, as far as I know;
just not what you'd expect from most machines.
We've got code using SCM2PTR and PTR2SCM in some places. We've got
code simply casting values in other places. Unless the uses are
carefully matched up to do the corresponding conversions in both
directions, we're practically guaranteeing that the code will never be
portable to the old Cray. Even without that, I'm skeptical whether a
Cray port of BDW-GC would be able to process our SCM objects there,
since apparently our SCM objects are represented rather differently
from native pointers.
We also cast function pointer types in places. Pointers are not
required to all have the same representation, nor to be passed or
returned in function calls the same way. There are also ABIs where
pointers are passed around one way, and integers another way. Take
the address of a function with one kind of argument, and call it
through a pointer to a function type with a different argument, and
the calling sequence may not match how the function attempts to access
its arguments.
Among modern general-purpose computers, the behavior's going to be
pretty consistent -- to some people, "modern general-purpose computer"
means x86 only, *maybe* one or possibly two other architectures,
definitely a flat address space and uniform pointer representations
the size of some standard integer type -- but try porting to older
systems or some embedded processors, and some of the assumptions start
to fail. Do we even have a good idea what the assumptions we're
making, beyond the basic requirements for a compliant C
implementation, are?
I know it's tempting to ignore older systems and only worry about
modern ones, but what of the people who might want to use Guile in
other packages? If we limit Guile's portability, we're also forcing
that limitation on any such other packages. One of my nagging
concerns, which I have avoided investigating thus far, is whether
Guile (and the BDW-GC library) will support all the platforms that
Emacs does. Do they support s390, sh3, or vax systems? How about AIX
4.2? All of those are listed in the configure script for Emacs. If
someone revives the VMS port of Emacs, will they be able to port Guile
and libgc (and libunistring and ...)?
The advantage of the STRICTNESS=2 code is that it forces additional
discipline; simple casts can't paper over all the conversions. It may
seem like an annoyance to treat "SCM" and "void *" and "int" as
requiring explicit conversions, but if someday someone tries porting
to a platform like the old Cray, C code written with the assumption
that "it's all just words (and we know what the representations look
like)" may cause them no end of headaches. Such an assumption *is*
valid when we start looking at code generation for specific
architectures. But despite any cracks about C being a "high level
assembly language", it *is* more abstract and such assumptions don't
hold true for C in the general case.
If all we were discussing was whether the "guile" program should be
available on older platforms, that would be one thing. But we're
talking about the extension library we want to promote for widespread
use, in GNU programs and presumably elsewhere. Should we really tell
people, "you have to choose between portability to these old or
uncommon platforms, and being able to use this extension library"?
Especially if they're already supporting old platforms and not yet
supporting Guile?
In my not-so-humble opinion, the onus should be on us to keep the
Guile library as portable as possible (and push implementors of the
libraries that libguile depends on in the same direction), and leave
it to the application writers to decide what they want to do in terms
of supporting old or unusual platforms, rather than having us impose
limitations on them.
</soapbox>
I still don't have any specific proposal to make STRICTNESS!=1 work
throughout our code, but I do expect it would be somewhat intrusive in
places. (For example, some macros that do "interesting" things with
the values they're passed, I'd probably want to change to inline
functions, at least when BUILDING_LIBGUILE under gcc, so we can do
type checking of the supplied values, and then add conversion calls or
casts or whatever as necessary. The static initialization macros
would almost certainly need changes.) So unless I've swayed some of
the maintainers, I'm not going to spend much more time on it.
In fact, if the general opinion is "screw the unusual platforms, let's
hard-code the default STRICTNESS=1 case and get rid of the rest so
people like Ken stop trying to play with it", I'm also willing to do
the coding for that, too. But as I've indicated, I do think it's the
wrong direction....
Ken
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: more compilation failures: -DSCM_DEBUG_TYPING_STRICTNESS=2
2009-11-18 5:52 ` Ken Raeburn
@ 2009-11-18 9:37 ` Ludovic Courtès
2009-11-18 20:40 ` Ken Raeburn
0 siblings, 1 reply; 16+ messages in thread
From: Ludovic Courtès @ 2009-11-18 9:37 UTC (permalink / raw)
To: guile-devel
Hi Ken,
I agree that we should strive to make Guile portable, especially since
we are to stuff it into Emacs.
From time to time, I test it on some “exotic” hardware architectures of
the GCC Compile Farm (MIPS, Alpha, PPC64, etc.), and it’s been working
pretty well so far. I also got accounts on Tru64, AIX, and now Solaris
and HP-UX, which I’m hoping to put to good use by the time we release 2.0.
That said, I’m not too worried about the Cray pointer thing. IOW, it’s
OK for me to live with potential Cray breakage until someone with access
to such a machine (how many are there around the world?) can come up
with a bug report or a fix.
Now, if ‘SCM_DEBUG_TYPING_STRICTNESS’ can help us prevent breakage,
that’s nice. I’ve never used it so far, and never felt the need to use
it, but I’d be glad to follow your lead on this matter. :-)
Thanks,
Ludo’.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: more compilation failures: -DSCM_DEBUG_TYPING_STRICTNESS=2
2009-11-18 9:37 ` Ludovic Courtès
@ 2009-11-18 20:40 ` Ken Raeburn
2009-11-18 21:18 ` Andy Wingo
2009-11-18 23:09 ` Ludovic Courtès
0 siblings, 2 replies; 16+ messages in thread
From: Ken Raeburn @ 2009-11-18 20:40 UTC (permalink / raw)
To: Ludovic Courtès; +Cc: guile-devel
On Nov 18, 2009, at 04:37, Ludovic Courtès wrote:
> From time to time, I test it on some “exotic” hardware architectures
> of
> the GCC Compile Farm (MIPS, Alpha, PPC64, etc.), and it’s been working
> pretty well so far. I also got accounts on Tru64, AIX, and now
> Solaris
> and HP-UX, which I’m hoping to put to good use by the time we
> release 2.0.
Actually, I wouldn't consider any of those terribly "exotic", unless
you're using one of the early Alphas that didn't support byte-access
operations. But at least we get some tests with strict memory
alignment requirements, etc. Windows testing would be kind of
important, too. Have access to any embedded systems? (Of course, if
they're not POSIX, the thread system would require some more porting
work... and it might show up areas where we've made other unwarranted
assumptions.)
Actually, Alpha is also interesting in that the spec permits weak
memory ordering -- so that one processor could execute "x = 1; y = 2;"
and even without the compiler playing games, a second processor may
see y modified before x. Such a machine can easily support C
(multiprocessor interactions are outside the spec) and POSIX (mutex
calls can incorporate memory barriers to force synchronization), but I
believe libguile assumes strict ordering between threads. I don't
know if the actual processor implementations or OSes permit such
reordering. Testing Guile on a multiprocessor system using weak
memory ordering would be interesting; I suspect, though, that it would
simply not work reliably.
> That said, I’m not too worried about the Cray pointer thing. IOW,
> it’s
> OK for me to live with potential Cray breakage until someone with
> access
> to such a machine (how many are there around the world?) can come up
> with a bug report or a fix.
It would be "better" in some sense if someone could try it out and let
us know for sure what the situation is -- if any of the machines still
exist. I wouldn't try to fix it for the Cray without someone out
there actively interested in using that version, but I don't want to
turn a blind eye to problems I'm confident would come up for people
in reasonable (if unusual) C environments. And I'm concerned that the
fixes would involve things like changing a macro, that currently works
with SCM or pointer types, into two macros, one for SCM values and one
for pointers -- that would mean an API change might be required in
order to finish a port.
> Now, if ‘SCM_DEBUG_TYPING_STRICTNESS’ can help us prevent breakage,
> that’s nice. I’ve never used it so far, and never felt the need to
> use
> it, but I’d be glad to follow your lead on this matter. :-)
That's one... ;-)
Ken
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: more compilation failures: -DSCM_DEBUG_TYPING_STRICTNESS=2
2009-11-18 20:40 ` Ken Raeburn
@ 2009-11-18 21:18 ` Andy Wingo
2009-11-18 23:09 ` Ludovic Courtès
1 sibling, 0 replies; 16+ messages in thread
From: Andy Wingo @ 2009-11-18 21:18 UTC (permalink / raw)
To: Ken Raeburn; +Cc: Ludovic Courtès, guile-devel
Hi :)
On Wed 18 Nov 2009 21:40, Ken Raeburn <raeburn@raeburn.org> writes:
> On Nov 18, 2009, at 04:37, Ludovic Courtès wrote:
>> Now, if ‘SCM_DEBUG_TYPING_STRICTNESS’ can help us prevent breakage,
>> that’s nice. I’ve never used it so far, and never felt the need to
>> use
>> it, but I’d be glad to follow your lead on this matter. :-)
>
> That's one... ;-)
I'm happy to have it help out, but "with other people" ;) Perhaps I can
be the one ensuring that it works as it currently does? ;)
Andy
--
http://wingolog.org/
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: more compilation failures: -DSCM_DEBUG_TYPING_STRICTNESS=2
2009-11-18 20:40 ` Ken Raeburn
2009-11-18 21:18 ` Andy Wingo
@ 2009-11-18 23:09 ` Ludovic Courtès
1 sibling, 0 replies; 16+ messages in thread
From: Ludovic Courtès @ 2009-11-18 23:09 UTC (permalink / raw)
To: Ken Raeburn; +Cc: guile-devel
Hi,
Ken Raeburn <raeburn@raeburn.org> writes:
> Actually, I wouldn't consider any of those terribly "exotic", unless
> you're using one of the early Alphas that didn't support byte-access
> operations.
And there’s also SPARC, which doesn’t support unaligned accessed (Linux
reifies them as SIGBUS, as on Alpha IIRC.)
> Windows testing would be kind of important, too. Have access to any
> embedded systems?
Neil regularly tests on MinGW:
http://autobuild.josefsson.org/guile/#GNU%20Guile-i586-pc-mingw32msvc .
[...]
> Testing Guile on a multiprocessor system using weak
> memory ordering would be interesting; I suspect, though, that it would
> simply not work reliably.
Hmm, I dunno, but there’s already much to be dealt with on multicore
x86(_64) IMO.
[...]
> I wouldn't try to fix it for the Cray without someone out
> there actively interested in using that version, but I don't want to
> turn a blind eye to problems I'm confident would come up for people
> in reasonable (if unusual) C environments.
Do you have specific platforms in mind? This Cray/Unicos pointer
representation really seems surreal to me, so I’d be glad to hear of
systems with similar singularities.
Thanks,
Ludo’.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: more compilation failures: -DSCM_DEBUG_TYPING_STRICTNESS=2
2009-09-01 6:23 more compilation failures: -DSCM_DEBUG_TYPING_STRICTNESS=2 Ken Raeburn
2009-09-01 6:26 ` Ken Raeburn
@ 2009-09-01 19:47 ` Ludovic Courtès
2009-09-01 22:29 ` Ken Raeburn
1 sibling, 1 reply; 16+ messages in thread
From: Ludovic Courtès @ 2009-09-01 19:47 UTC (permalink / raw)
To: guile-devel
Hi Ken,
Ken Raeburn <raeburn@raeburn.org> writes:
> Compiling with SCM_DEBUG_TYPING_STRICTNESS=2 as discussed in __scm.h
Another compilation flag that must be rarely used. :-)
Do you find it useful?
> It also means constant values for static initializers ("{ { BITS } }")
> have a different form from run-time expressions generating certain
> values ("scm_pack (BITS)" calls an inline function), and comparisons
> can't be done with "==" and "!=". (In fact, tags.h already says "SCM
> values can not be compared by using the operator ==", right above the
> definition of scm_is_eq.)
>
> Guess what we're also doing? :-)
> And I haven't even tried compiling Ludovic's bdw-gc-static-alloc
> branch yet, just master.
Indeed, we're in trouble.
> #1: We continue to not support static initialization.
[...]
> #1a: Extend #1 later with whatever internal macros are needed to
> provide the right initialization syntax for constructs used in bdw-gc-
> static-alloc based on the STRICTNESS setting.
>
> #1b: Try to supplement #1 with changes to SCM_PACK or SCM_MAKIFLAG to
> make it not considered a compile-time constant even with STRICTNESS<2
> and thus SCM_UNSPECIFIED, SCM_BOOL_F, etc are never suitable for
> static initialization, catching this problem earlier in the future.
[...]
> #1c: Try to supplement #1 by defaulting to STRICTNESS=2 on platforms
> where the union is passed and returned the same way as the pointer or
> integer in function calls
[...]
> #2: Drop STRICTNESS=2 support and really support static initialization
> with the current macros.
>
> #3: Keep STRICTNESS=2 support, and support static initialization, even
> for application code, with a bunch of new macros.
My preference is for #2 because: (1) I've never used it ;-), and
(2) we're moving away from C anyway. Hmm, weak arguments maybe.
Anyway, in the meantime, we can conditionalize static initialization
stuff from bdw-gc-static-alloc on STRICTNESS == 0 and keep everyone
happy.
Does that sound reasonable?
> It looks like the eval code is going to be annoying too
I wouldn't worry much about this one either as its probably doomed, once
Andy's eval cleanup work is mature.
Things have been moving too fast lately!
Thanks,
Ludo'.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: more compilation failures: -DSCM_DEBUG_TYPING_STRICTNESS=2
2009-09-01 19:47 ` Ludovic Courtès
@ 2009-09-01 22:29 ` Ken Raeburn
2009-09-02 8:08 ` Ludovic Courtès
0 siblings, 1 reply; 16+ messages in thread
From: Ken Raeburn @ 2009-09-01 22:29 UTC (permalink / raw)
To: Ludovic Courtès; +Cc: guile-devel
On Sep 1, 2009, at 15:47, Ludovic Courtès wrote:
>> Compiling with SCM_DEBUG_TYPING_STRICTNESS=2 as discussed in __scm.h
>
> Another compilation flag that must be rarely used. :-)
>
> Do you find it useful?
Not so far. :-) There seems to be a lot of otherwise correct code
making assumptions about using casts or "==" or whatever; I haven't
sorted out whether there are actual bugs being flagged in there too.
The corresponding code in Emacs has helped me track down code that was
being sloppy about mixing integers and Lisp values, and that was good,
since I'm trying to change things so that integers represented in Lisp
have bit patterns different from the integers themselves, so you
really need to make the distinction. But IIRC it took a while to make
it work again, because nothing was really using it when I started
poking at it.
In the Guile case, I'm a tiny bit concerned about some of the pointer/
int games played (e.g., I'm pretty sure C99 does not guarantee that
you can convert an arbitrary uintptr_t value to pointer and back and
be guaranteed of getting the original value... but I don't know of a
platform that actually violates that assumption), but only a tiny bit.
> My preference is for #2 because: (1) I've never used it ;-), and
> (2) we're moving away from C anyway. Hmm, weak arguments maybe.
>
> Anyway, in the meantime, we can conditionalize static initialization
> stuff from bdw-gc-static-alloc on STRICTNESS == 0 and keep everyone
> happy.
>
> Does that sound reasonable?
Sure. Actually, STRICTNESS=1 is the default -- 0 makes SCM an
integer, 1 makes it a pointer to a struct, which adds a little more
type safety, and 2 makes it a union, which breaks casting,
initialization, etc.
>> It looks like the eval code is going to be annoying too
>
> I wouldn't worry much about this one either as its probably doomed,
> once
> Andy's eval cleanup work is mature.
>
> Things have been moving too fast lately!
I'm not going to complain about that! :-)
Ken
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: more compilation failures: -DSCM_DEBUG_TYPING_STRICTNESS=2
2009-09-01 22:29 ` Ken Raeburn
@ 2009-09-02 8:08 ` Ludovic Courtès
2009-09-02 18:17 ` Ken Raeburn
2009-09-08 23:37 ` Neil Jerram
0 siblings, 2 replies; 16+ messages in thread
From: Ludovic Courtès @ 2009-09-02 8:08 UTC (permalink / raw)
To: guile-devel
Hi!
Ken Raeburn <raeburn@raeburn.org> writes:
> In the Guile case, I'm a tiny bit concerned about some of the pointer/
> int games played (e.g., I'm pretty sure C99 does not guarantee that
> you can convert an arbitrary uintptr_t value to pointer and back and
> be guaranteed of getting the original value... but I don't know of a
> platform that actually violates that assumption), but only a tiny bit.
Really? I think the whole purpose of `uintptr_t' is to allow that,
isn't it?
>> Anyway, in the meantime, we can conditionalize static initialization
>> stuff from bdw-gc-static-alloc on STRICTNESS == 0 and keep everyone
>> happy.
>>
>> Does that sound reasonable?
>
> Sure. Actually, STRICTNESS=1 is the default -- 0 makes SCM an
> integer, 1 makes it a pointer to a struct, which adds a little more
> type safety, and 2 makes it a union, which breaks casting,
> initialization, etc.
Oh, right.
Thanks,
Ludo'.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: more compilation failures: -DSCM_DEBUG_TYPING_STRICTNESS=2
2009-09-02 8:08 ` Ludovic Courtès
@ 2009-09-02 18:17 ` Ken Raeburn
2009-09-03 11:48 ` Ludovic Courtès
2009-09-08 23:37 ` Neil Jerram
1 sibling, 1 reply; 16+ messages in thread
From: Ken Raeburn @ 2009-09-02 18:17 UTC (permalink / raw)
To: Ludovic Courtès; +Cc: guile-devel
On Sep 2, 2009, at 04:08, Ludovic Courtès wrote:
>> In the Guile case, I'm a tiny bit concerned about some of the
>> pointer/
>> int games played (e.g., I'm pretty sure C99 does not guarantee that
>> you can convert an arbitrary uintptr_t value to pointer and back and
>> be guaranteed of getting the original value... but I don't know of a
>> platform that actually violates that assumption), but only a tiny
>> bit.
>
> Really? I think the whole purpose of `uintptr_t' is to allow that,
> isn't it?
It's the other way around that's guaranteed to work: void* ->
(u)intptr_t -> void*. So any value originally derived from a valid
pointer will work, but arbitrary values may not. Also, C99 talks
about uintptr_t as being capable of holding a converted pointer-to-
void; strictly speaking, I don't think it requires that a direct
conversion from/to any other pointer type (except possibly char*) work
the same way.
So, for example, uintptr_t may have 64 bits on a machine that uses 48-
bit pointers (segment+offset? also, some embedded processors have non-
power-of-two pointer or integer sizes, though I don't know whether
they have pointer and int types matching in size); pointers may have
trapping representations (invalid segment number?); storing an integer
value into a pointer register may cause certain bits to be masked off;
manipulation of pointer values in general registers may not preserve
bits known by the compiler not to be set in any valid or null
pointers; etc.
And then there's the whole NULL-vs-0 thing -- "0" is a null pointer
constant in source code, but strictly speaking the compiler produces a
null pointer constant there; it doesn't imply that the null pointer
has the same binary representation as 0, nor that a non-constant zero
value when cast to a pointer will be a null pointer, nor that memset(,
0,) gives you null pointers, nor that a null pointer cast to uintptr_t
will have the value 0, etc.
(For example, in an architecture with one pointer format for segment +
word offset, and a second representation for segment + word offset +
bit offset into word, a void* may require the second form, but a
struct pointer might use the former, if all structs are required to be
word-aligned. And converting a pointer to uintptr_t could just copy
bits around, giving consistent results only if you use the same
pointer form consistently in the conversions. And all-bits-zero may
store an invalid segment number that could lead to a trap when loaded
into a pointer register, and a "null pointer" may be represented with
a reserved non-zero segment number. This is not completely
theoretical... I once used a platform with multiple pointer types and
a null pointer representation using segment number -1, which could be
loaded without faulting but not dereferenced, but I'm rusty on some of
the details, and never got familiar with the C environment on it.)
Like I said, most platforms I know of, and all I know of that we're
likely to care about, will still meet these assumptions to the best of
my knowledge, so it's probably not a big problem. But as a bit of a
language pedant, I did notice...
Ken
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: more compilation failures: -DSCM_DEBUG_TYPING_STRICTNESS=2
2009-09-02 18:17 ` Ken Raeburn
@ 2009-09-03 11:48 ` Ludovic Courtès
0 siblings, 0 replies; 16+ messages in thread
From: Ludovic Courtès @ 2009-09-03 11:48 UTC (permalink / raw)
To: guile-devel
Hi!
Ken Raeburn <raeburn@raeburn.org> writes:
> On Sep 2, 2009, at 04:08, Ludovic Courtès wrote:
>>> In the Guile case, I'm a tiny bit concerned about some of the
>>> pointer/
>>> int games played (e.g., I'm pretty sure C99 does not guarantee that
>>> you can convert an arbitrary uintptr_t value to pointer and back and
>>> be guaranteed of getting the original value... but I don't know of a
>>> platform that actually violates that assumption), but only a tiny
>>> bit.
>>
>> Really? I think the whole purpose of `uintptr_t' is to allow that,
>> isn't it?
>
> It's the other way around that's guaranteed to work: void* ->
> (u)intptr_t -> void*. So any value originally derived from a valid
> pointer will work, but arbitrary values may not.
[...]
Hmm, I see. Thanks for the interesting explanation!
Now I understand that I've been lucky enough to live in a beautiful
world with power-of-two pointer types, NULL == 0, etc. ;-)
Thanks,
Ludo'.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: more compilation failures: -DSCM_DEBUG_TYPING_STRICTNESS=2
2009-09-02 8:08 ` Ludovic Courtès
2009-09-02 18:17 ` Ken Raeburn
@ 2009-09-08 23:37 ` Neil Jerram
2009-09-09 1:41 ` Ken Raeburn
1 sibling, 1 reply; 16+ messages in thread
From: Neil Jerram @ 2009-09-08 23:37 UTC (permalink / raw)
To: Ludovic Courtès, Ken Raeburn; +Cc: guile-devel
ludo@gnu.org (Ludovic Courtès) writes:
>>> Anyway, in the meantime, we can conditionalize static initialization
>>> stuff from bdw-gc-static-alloc on STRICTNESS == 0 and keep everyone
>>> happy.
>>>
>>> Does that sound reasonable?
>>
>> Sure. Actually, STRICTNESS=1 is the default -- 0 makes SCM an
>> integer, 1 makes it a pointer to a struct, which adds a little more
>> type safety, and 2 makes it a union, which breaks casting,
>> initialization, etc.
>
> Oh, right.
I've never used the non-default STRICTNESS either, and static
initialization sounds like a nice feature; so I'm also happy with
blowing away STRICTNESS 2.
Then, given that you (Ken) think that STRICTNESS 0 doesn't work
either, I'd favour hardcoding the STRICTNESS 1 macros and then
discarding the whole STRICTNESS concept.
Neil
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: more compilation failures: -DSCM_DEBUG_TYPING_STRICTNESS=2
2009-09-08 23:37 ` Neil Jerram
@ 2009-09-09 1:41 ` Ken Raeburn
0 siblings, 0 replies; 16+ messages in thread
From: Ken Raeburn @ 2009-09-09 1:41 UTC (permalink / raw)
To: Neil Jerram; +Cc: Ludovic Courtès, guile-devel
On Sep 8, 2009, at 19:37, Neil Jerram wrote:
> Then, given that you (Ken) think that STRICTNESS 0 doesn't work
> either, I'd favour hardcoding the STRICTNESS 1 macros and then
> discarding the whole STRICTNESS concept.
That (0 not working) is only a guess, but I'll try it out to see.
I kind of like keeping STRICTNESS 2, because I'm a bit uncomfortable
with the amount of casting going on in some places, and the degree to
which it could (theoretically) be masking actual bugs. But if opinion
goes against me I'm willing to work on the changes you describe.
Ken
^ permalink raw reply [flat|nested] 16+ messages in thread
* more compilation failures: -DSCM_DEBUG_TYPING_STRICTNESS=2
@ 2009-09-01 4:52 Ken Raeburn
0 siblings, 0 replies; 16+ messages in thread
From: Ken Raeburn @ 2009-09-01 4:52 UTC (permalink / raw)
To: guile-devel
Compiling with SCM_DEBUG_TYPING_STRICTNESS=2 causes SCM to be defined
as a union type (though the comments say a struct type), which
enhances the type checking by making random conversions and casts to
and from pointer and integer types not work without going through the
correct conversion macros/functions.
Problem is, we're doing some of those.
It also means constant values for static initializers ("{ { BITS } }")
have a different form from run-time expressions generating certain
values ("scm_pack (BITS)" calls an inline function), and comparisons
can't be done with "==" and "!=". (In fact, tags.h already says "SCM
values can not be compared by using the operator ==", right above the
definition of scm_is_eq.)
Guess what we're also doing? :-)
And I haven't even tried compiling Ludovic's bdw-gc-static-alloc
branch yet, just master.
I can clean some of this up trivially -- SCM_PACK/SCM_UNPACK as
needed, change == to scm_is_eq. The initializers make it slightly
less trivial, and I can imagine different courses of action.
#1: We continue to not support static initialization. Move most of
the initializations in the library to the per-file init functions, and
for stuff like the ra_iproc tables in array-map.c we may want *one*
internal initializer macro (SCM_I_UNSPECIFIED_INIT or
SCM_I_UNDEFINED_INIT? maybe even something zero-valued) for filling in
slots in static structures without getting compiler warnings about
missing initializers.
#1a: Extend #1 later with whatever internal macros are needed to
provide the right initialization syntax for constructs used in bdw-gc-
static-alloc based on the STRICTNESS setting.
#1b: Try to supplement #1 with changes to SCM_PACK or SCM_MAKIFLAG to
make it not considered a compile-time constant even with STRICTNESS<2
and thus SCM_UNSPECIFIED, SCM_BOOL_F, etc are never suitable for
static initialization, catching this problem earlier in the future. I
believe a use of a comma expression will suffice, but finding a form
that doesn't generate compiler warnings and doesn't generate run-time
code could be tricky. (Though, it becomes easier if we require only
no performance impact when optimizing and with ... what, inline
function support? gcc?)
#1c: Try to supplement #1 by defaulting to STRICTNESS=2 on platforms
where the union is passed and returned the same way as the pointer or
integer in function calls, and where there isn't a significant
performance impact. Probably selected via cpp macros in __scm.h,
since an autoconf feature test would be difficult at best, and still
specific to the compiler used for building libguile and not the one
used to build the application. This helps us avoid the "==" and
random casting part of the problem better in the future. Mac OS X
(10.5, Intel) seems to use the same calling convention both ways in
one simple test, though I haven't tried performance testing.
#2: Drop STRICTNESS=2 support and really support static initialization
with the current macros.
#3: Keep STRICTNESS=2 support, and support static initialization, even
for application code, with a bunch of new macros.
Thoughts? My preference is for #1 now, and #1a/b/c when convenient or
needed.
Ken
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2009-11-18 23:09 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-09-01 6:23 more compilation failures: -DSCM_DEBUG_TYPING_STRICTNESS=2 Ken Raeburn
2009-09-01 6:26 ` Ken Raeburn
2009-09-16 19:20 ` Andy Wingo
2009-11-18 5:52 ` Ken Raeburn
2009-11-18 9:37 ` Ludovic Courtès
2009-11-18 20:40 ` Ken Raeburn
2009-11-18 21:18 ` Andy Wingo
2009-11-18 23:09 ` Ludovic Courtès
2009-09-01 19:47 ` Ludovic Courtès
2009-09-01 22:29 ` Ken Raeburn
2009-09-02 8:08 ` Ludovic Courtès
2009-09-02 18:17 ` Ken Raeburn
2009-09-03 11:48 ` Ludovic Courtès
2009-09-08 23:37 ` Neil Jerram
2009-09-09 1:41 ` Ken Raeburn
-- strict thread matches above, loose matches on Subject: below --
2009-09-01 4:52 Ken Raeburn
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).