SGCL - Garbage Collector for C++

R

Richard Herring

Let me know when you figure out why, in Java, you have to throw all
these try/catch blocks around, every time you need to deal with files
or sockets, in order not to run out of available file descriptors.

Maybe that would be because garbage collection is for recycling memory,
not for managing the lifetime of external resources.

Next?
So much for garbage collection.

So much for using garbage collection for lifetime management, indeed.
 
J

James Kanze

Here's another hair for you to split: ______________________________

Talking about one of the most fundamental aspects of C++ is not
splitting hairs. Just because you don't know C++ doesn't mean
that the language will change to suit your misconceptions.
Anyone who is not involved with splitting hairs, for a living,
would clearly understand that I was referring to the fact that
"delete" does both: destruction and memory reclamation. It's
one shot, in C++.

Anyone who knows the C++ object model knows that the delete
operator (like the new operator) does two very distinct things.
Involving different functions. In the absense of garbage
collection, it was often convenient to associate them---thus, a
single operator. But they are, and always have been two
distinct operations. The distinction is fundamental to the C++
object model.
Damn right! There's no such thing as "delete", in C++, which
handles both object destruction and memory release. There's a
"foo", that does the first part, and "bar", that does the
second one. My mistake.

Yup. Your mistake. I'd suggest you read a little about how C++
works. You might start with the definition of the delete
operator, §5.3.5. And sections §3.7 and §3.8, of course: the
first treats storage duration, and the second object lifetime.
(The standard considers them different enough to treat them in
two separate sections.)
Why do you keep repeating this, that object destruction and
memory release are two completely separate processes in C++,
when it's been explained to you that it's completely false.

Nothing has been explained to me. The standard says that they
are two distinct operations. You've not said anything which
would make me doubt the standard.
Maybe on your planet C++ works this way, but not on this one.

Try reading the standard sometime. Or even learning some of the
more basics of the language.
And how do you expect to arrive to such a conclusion? A random
number generator? Yippee! It evaluated to 0.53 -- must mean
that no further pointers remain, and we can reclaim the
object.

Are you being intentionally stupid, or have you really never
heard of assertions? Or programming by contract? Or writing
robust code?
Not on my planet, where it works every time it's used
properly, and garbage collection is an ugly hack for the lazy
asses who can't be bothered to track and manage their objects,
properly.

That planet must not be in the known universe, because it
violates all proven rules of logic. Shared_ptr doesn't work in
all cases; you need all sorts of hacks to make it work (break
cycles, etc.). In the absense of garbage collection, it's often
better than nothing, but it's certainly not as good as the real
thing.
Repeating the same absurdity a given number of times won't
suddenly turn it into sense.

The difference is that my "absurdity" is based on the C++
standard, the way C++ really works, the proposal to add garbage
collection to C++, and actual implementations of garbage
collection. What's yours based on, except your imagination and
your misunderstanding of C++.
The whole and the only purpose of garbage collection is to
clean up after yourself, when you can't be bothered to do it
properly.

The whole and only purpose of garbage collection is to manage
memory. At least, that's what the authors of the proposal to
add it to C++ say, and that's what the authors of the garbage
collector I use say.

Inventing something else and calling it garbage collection may
satify some fancy of yours, but it isn't very intellectually
honest.
That's the sole and the only purpose for it, because if you do
know what you're doing, you simply don't need garbage
collection. Not in C++, at least.

Do you actually read the posts you respond to? I've stated
several times: garbage collection reduces the amount of work you
need to do. That's all. It won't turn an incompetent
programmer miraculously into a competent one. If you know what
you are doing, you don't need garbage collection. Nor
templates. Nor classes. They just mean that you need less time
and effort to acheive the same ends.
Brilliant! "I'm too stupid to know how to track my objects'
lifetime, so I'll just use garbage collection in some twisted
way, in order to save my lazy ass."

I suppose you've never seen a program with an error. Neither in
the code you write, or that of your collegues. The fact remains
that good code makes extensive use of assertions, to detect
error conditions.
I call "knowing how to do your job, WRT class design an
implementation" more robust than using an ugly, revolting hack
like C++-based garbage collection.

It sounds more to me that you don't know what "knowing how to do
your job" involves, at least if your job is in software
engineering.
There's no such thing as garbage collection in "basic C++
object mode." The formal language just does not define
anything of that sort. Feel free to cite the part of ISO/IEC
14882:2003 that defines garbage collection for "basic C++
object mode". Whatever that is.

It would help, again, if you'd read what you are replying to.
The C++ standard definitly separates memory allocation from
object lifetime. Two very distinct things. And the role of
garbage collection in C++ is the handle memory allocation, not
object lifetime. Regardless of what you claim.
Garbage collection for C++ always involves some third-party
slapdash code that seems to compete with Boost for the gold
prize in the C++ obfuscation context.

Have you actually used it? Have you read the proposals for it?
Do you actually know the least thing about what you are saying?
Actually, reflecting on the last 10+ years of looking at C++
code in financial apps -- that are responsible for moving huge
volumes of business critical market data -- I do not recall
even a single instance of anyone using anything can even be
remotely described, in some nightmarish context, as "garbage
collection." Sorry, but established facts disagree with your
theories.

Really. I've worked on banking applications which used garbage
collection.
"C++ garbage collection" is the very essence of "unnecessary work".

Writing a garbage collector for C++ isn't trivial, but as others
have already done it.
You better sit down, because the following may come as a shock to you.
Sitting down? Ok.
Here's a newsflash: there's plenty of "robust software" going
around that does not involve garbage collection. Well, how'd
that happen, huh?

People spent more time implementing it than was necessary.
Can't you read? It's a tool. There's also plenty of "robust
software" going around that's written in assembler. When I have
a choice, however, I use a high level language---I know how to
write robust software in assembler, but it's a lot more work.
That's your opinion.

It's practically the definition of an engineer.
If I ever meet some candidate who walks off the street, and
starts spouting something or other about the wonders of
garbage collection in C++,

Strawman. Who's talking about the wonders of anything. We're
just talking about a tool to improve programmer productivity and
program reliability.
I'll politely thank him, strike his name off the list, and
move on to the next one. Nobody who knows what he's doing, in
C++, has any use for this garbage collection nonsense.

Except, perhaps, the professionals who are using it. (FWIW: one
of the major proponents of the proposal in C++ is Bjarne
Stroustrup. Are you saying that he doesn't know what he's
doing?)

Anyway, I give up. You've shown that you don't really know C++,
nor anything about software engineering. Worse, you've shown
that you're unwilling to learn. I just hope I never have to use
anything you've written.
 
I

Ioannis Vranos

James said:
There are too many "destructors" floating around there to please
me. When discussing such issues, I prefer to use distinct
names: dispose or destruct terminates the lifetime of the
object---regardless of how or where it was allocated, and
finalize is a function which is called by the garbage collector,
when it collects the memory. Concerning finalize, there are two
important points to remember: objects with an explicit disposal
function might not (in fact, shouldn't) be alive when it is
called, and it won't be called on local or static objects.
Calling both destructors just adds to the confusion. (For that
matter, speaking of "destructors" in this context may add to the
confusion, since the word more often applies to a concrete C++
language concept rather than the more general concept.)


An example of a C++/CLI class:

ref class managed_class
{
std::string s;

// ...

public:
managed_class(const std::string &x):s(x)
{}

~managed_class()
{
// ...
}

// Finalizer, it is called by GC if the destructor has not been used
!managed_class()
{
// ...
}

// ...
};


Under C++/CLI, for a managed class (which can contain native objects
too) with a finalizer and a destructor, when an object reaches the end
of its scope or is deleted explicitly after it was created via gcnew
operator, the destructor is called and the object is destroyed at that
point, and is not garbage collected later.

If the destructor has not been called, when GC destroys the object, the
"finalizer" is called.


I think this approach is elegant and something similar can be adopted
for ISO C++, or perhaps ISO C++ can make C++/CLI a subset, since CLI is
a VM standard too. That is, ISO C++ to not define a specific garbage
collector standard, but rely on existing standardised ones like CLI.
 
J

jlindrud

Under C++/CLI, for a managed class (which can contain native objects
too) with a finalizer and a destructor, when an object reaches the end
of its scope or is deleted explicitly after it was created via gcnew
operator, the destructor is called and the object is destroyed at that
point, and is not garbage collected later.

If the destructor has not been called, when GC destroys the object, the
"finalizer" is called.

I think this approach is elegant and something similar can be adopted
for ISO C++, or perhaps ISO C++ can make C++/CLI a subset, since CLI is
a VM standard too. That is, ISO C++ to not define a specific garbage
collector standard, but rely on existing standardised ones like CLI.


That would be a terrible mistake. Having the garbage collector run
user code of any kind is hugely inappropriate, and exactly what landed
C# and Java in the resource management mess that they're in.

When C++ programmers complain about garbage collection, it's almost
always because they've been exposed to how garbage collection works in
either C# or Java.

And BTW, Microsoft publishing a spec for CLI does not make it a
"standard".
 
I

Ioannis Vranos

That would be a terrible mistake. Having the garbage collector run
user code of any kind is hugely inappropriate, and exactly what landed
C# and Java in the resource management mess that they're in.

I think the C++/CLI approach is more elegant than C#/CLI (also a
standard) and Java/Java, because it separates the notion of native code
and garbage collected code, while it allows native code and managed code
to be intermixed.

I do not think C++ must move to an aprroach of a C++-only VM, I think
the notions of native code and managed code must be kept separate while
they can be intermixed at the same time. Also C++/CLI provides the
syntax of "objects in the stack" which also allows RAII to work with
managed types too.

When C++ programmers complain about garbage collection, it's almost
always because they've been exposed to how garbage collection works in
either C# or Java.

Myself have not been exposed to Java/Java and C#/.NET, only to "managed
extensions of C++", the ancestor of C++/CLI.

And BTW, Microsoft publishing a spec for CLI does not make it a
"standard".


Yes, MS did push it forward, but it is an ECMA standard (and if I recall
well, both C++/CLI and CLI must have become ISO standards too).
 
I

Ioannis Vranos

That would be a terrible mistake. Having the garbage collector run
user code of any kind is hugely inappropriate, and exactly what landed
C# and Java in the resource management mess that they're in.

I think the C++/CLI approach is more elegant than C#/CLI (also a
standard) and Java/Java, because it separates the notion of native code
and garbage collected code, while it allows native code and managed code
to be intermixed.

I do not think C++ must move to an approach of a C++-only VM, I think
the notions of native code and managed code must be kept separate while
they can be intermixed at the same time. Also C++/CLI provides the
syntax of "objects in the stack" which also allows RAII to work with
managed types too.

When C++ programmers complain about garbage collection, it's almost
always because they've been exposed to how garbage collection works in
either C# or Java.

Myself have not been exposed to Java/Java and C#/.NET, only to "managed
extensions of C++", the ancestor of C++/CLI.

And BTW, Microsoft publishing a spec for CLI does not make it a
"standard".


Yes, MS did push it forward, but it is an ECMA standard (and if I recall
well, both C++/CLI and CLI must have become ISO standards too).
 
I

Ioannis Vranos

Minor correction: Consider the phrase "Java/Java" being "Java/JVM", as
more accurate.
 
P

Pete Becker

Yes, MS did push it forward, but it is an ECMA standard (and if I
recall well, both C++/CLI and CLI must have become ISO standards too).

C++/CLI did not become an ISO standard.
 
J

jlindrud

But Microsoft getting ECMA to bless it does.

--


I guess it depends on what you mean by standard. The ISO C++ standard
is in my view an excellent example of an industry standard, with broad
industry support and consent. In particular there are many separate
and competing implementations, and a broad range of industry input to
the standardization process.

AFAICT those qualities don't apply to the ECMA C++/CLI standard. It
would be better described as a formal standard, and as such is little
more than a rigorous specification.

Casually referring to them both as "standards" is rather misleading.
But unfortunately rather common.

-jarl.
 
S

Sam

That would be a terrible mistake. Having the garbage collector run
user code of any kind is hugely inappropriate, and exactly what landed
C# and Java in the resource management mess that they're in.

And that is precisely why, at $day$job$, someone's currently busy rewriting
a latency-sensitive realtime application from Java into C++. Having the VM
take a powder, at random times, to clean up its heap, gets old very quickly.
When C++ programmers complain about garbage collection, it's almost
always because they've been exposed to how garbage collection works in
either C# or Java.

Amen.

P.S. And the dude who's currently rewriting all that Java code in C++ is
not, I repeat, is NOT, using some loopy C++-based garbage collection
framework or library.



-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)

iD8DBQBHzJZYx9p3GYHlUOIRAsHhAJ47WtYenHsg1noRM/TheMEE8dNCXQCcCp53
ntZGVxvnAgMOWxe6Yl3oQ3o=
=sT5P
-----END PGP SIGNATURE-----
 
J

Jerry Coffin

(e-mail address removed)>, (e-mail address removed)
says...

[ ... ]
Yes. In practice, the C++ committee is at a juncture.
Independantly of any technical considerations, if the next
version of the standard doesn't support garbage collection and
threads, C++ is dead in the water---it will end up in the same
state as C, with a lot of older people used to it who continue
to use it, and argue in favor of it, because it's what they
know, but with less and less new applications being implemented
in it. (Alternatively, the major compiler vendors will simply
copy Microsoft, implement CLI, and call it C++. And the ISO
standard becomes irrelevant. And that's not a scenario I want
to see.)

N2287 attempts (but IMO, mostly fails) to do that. Truly supporting
garbage collection is, IMO, extraordinarily difficult. The problem is
that garbage collection is intended to have no externally visible effect
on the program. Since the standard's requirements are written in terms
of externally visible effects, actually requiring garbage collection is
essentially impossible. The closest N2287 comes is a non-normative note:

[Note: For garbage collected programs, a high quality hosted implemen-
tation should attempt to maximize the amount of unreachable memory it
reclaims. —end note ]

N2287 _does_ contain various ancillary requirements, such as for library
functions to control garbage collection, but in the end none of it
guarantees much of anything, since turning garbage collection on does
nothing more than enable the possibility of the implementation following
the advice of a non-normative note.

I don't think the future of C++ depends particularly heavily on garbage
collection, but I do think that if garbage collection is to be added,
there should at least be an attempt at doing it reasonably well. If
we're going to make it undefined behavior to do the things that can/will
break garbage collection, I think we should impose the (extremely few)
added restrictions necessary to allow an implementation to use a _good_
garbage collector.

It appears to me that this requires only one additional restriction:
that the program not depend in any way on the bit patterns stored in
pointers, such as hashing a pointer and later assuming that a pointer to
the same data will necessarily hash to the same value. We should also
make it undefined behavior to take a pointer value, store it into a non-
pointer type, and convert it back to a pointer, and then dereference the
result. In fact, I'm not sure that's really guaranteed to work now
(since there may not be any other type capable of holding a pointer
value) -- but I think it should be made explicit that it produces
undefined behavior. At the same time, pointers would retain their
original ordering (e.g. with an array, or as defined by std::less for
pointers to independent objects).

This restriction allows a great deal more flexibility in the design of
the collector itself, while imposing only a minimal burden on the
programmer. The burden is so minimal, in fact, that every piece of code
I've found that meets the requirements in N2287 also meets this
requirement, more or less by accident. As mentioned above, hashing a
pointer wouldn't, but I've yet to see that in real code.
 
P

peter koch

(e-mail address removed)>, (e-mail address removed)
says...

[ ... ]
Yes. In practice, the C++ committee is at a juncture.
Independantly of any technical considerations, if the next
version of the standard doesn't support garbage collection and
threads, C++ is dead in the water---it will end up in the same
state as C, with a lot of older people used to it who continue
to use it, and argue in favor of it, because it's what they
know, but with less and less new applications being implemented
in it. (Alternatively, the major compiler vendors will simply
copy Microsoft, implement CLI, and call it C++. And the ISO
standard becomes irrelevant. And that's not a scenario I want
to see.)

N2287 attempts (but IMO, mostly fails) to do that. Truly supporting
garbage collection is, IMO, extraordinarily difficult. The problem is
that garbage collection is intended to have no externally visible effect
on the program. Since the standard's requirements are written in terms
of externally visible effects, actually requiring garbage collection is
essentially impossible. The closest N2287 comes is a non-normative note:

[Note: For garbage collected programs, a high quality hosted implemen-
tation should attempt to maximize the amount of unreachable memory it
reclaims. --end note ]

N2287 _does_ contain various ancillary requirements, such as for library
functions to control garbage collection, but in the end none of it
guarantees much of anything, since turning garbage collection on does
nothing more than enable the possibility of the implementation following
the advice of a non-normative note.

I don't think the future of C++ depends particularly heavily on garbage
collection, but I do think that if garbage collection is to be added,
there should at least be an attempt at doing it reasonably well. If
we're going to make it undefined behavior to do the things that can/will
break garbage collection, I think we should impose the (extremely few)
added restrictions necessary to allow an implementation to use a _good_
garbage collector.

It appears to me that this requires only one additional restriction:
that the program not depend in any way on the bit patterns stored in
pointers, such as hashing a pointer and later assuming that a pointer to
the same data will necessarily hash to the same value. We should also
make it undefined behavior to take a pointer value, store it into a non-
pointer type, and convert it back to a pointer, and then dereference the
result. In fact, I'm not sure that's really guaranteed to work now
(since there may not be any other type capable of holding a pointer
value) -- but I think it should be made explicit that it produces
undefined behavior. At the same time, pointers would retain their
original ordering (e.g. with an array, or as defined by std::less for
pointers to independent objects).

This restriction allows a great deal more flexibility in the design of
the collector itself, while imposing only a minimal burden on the
programmer. The burden is so minimal, in fact, that every piece of code
I've found that meets the requirements in N2287 also meets this
requirement, more or less by accident. As mentioned above, hashing a
pointer wouldn't, but I've yet to see that in real code.

It would break some of my code which hashes on a pointer.

/Peter
 
I

Ioannis Vranos

peter said:
(e-mail address removed)>, (e-mail address removed)
says...

[ ... ]
Yes. In practice, the C++ committee is at a juncture.
Independantly of any technical considerations, if the next
version of the standard doesn't support garbage collection and
threads, C++ is dead in the water---it will end up in the same
state as C, with a lot of older people used to it who continue
to use it, and argue in favor of it, because it's what they
know, but with less and less new applications being implemented
in it. (Alternatively, the major compiler vendors will simply
copy Microsoft, implement CLI, and call it C++. And the ISO
standard becomes irrelevant. And that's not a scenario I want
to see.)
N2287 attempts (but IMO, mostly fails) to do that. Truly supporting
garbage collection is, IMO, extraordinarily difficult. The problem is
that garbage collection is intended to have no externally visible effect
on the program. Since the standard's requirements are written in terms
of externally visible effects, actually requiring garbage collection is
essentially impossible. The closest N2287 comes is a non-normative note:

[Note: For garbage collected programs, a high quality hosted implemen-
tation should attempt to maximize the amount of unreachable memory it
reclaims. --end note ]

N2287 _does_ contain various ancillary requirements, such as for library
functions to control garbage collection, but in the end none of it
guarantees much of anything, since turning garbage collection on does
nothing more than enable the possibility of the implementation following
the advice of a non-normative note.

I don't think the future of C++ depends particularly heavily on garbage
collection, but I do think that if garbage collection is to be added,
there should at least be an attempt at doing it reasonably well. If
we're going to make it undefined behavior to do the things that can/will
break garbage collection, I think we should impose the (extremely few)
added restrictions necessary to allow an implementation to use a _good_
garbage collector.

It appears to me that this requires only one additional restriction:
that the program not depend in any way on the bit patterns stored in
pointers, such as hashing a pointer and later assuming that a pointer to
the same data will necessarily hash to the same value. We should also
make it undefined behavior to take a pointer value, store it into a non-
pointer type, and convert it back to a pointer, and then dereference the
result. In fact, I'm not sure that's really guaranteed to work now
(since there may not be any other type capable of holding a pointer
value) -- but I think it should be made explicit that it produces
undefined behavior. At the same time, pointers would retain their
original ordering (e.g. with an array, or as defined by std::less for
pointers to independent objects).

This restriction allows a great deal more flexibility in the design of
the collector itself, while imposing only a minimal burden on the
programmer. The burden is so minimal, in fact, that every piece of code
I've found that meets the requirements in N2287 also meets this
requirement, more or less by accident. As mentioned above, hashing a
pointer wouldn't, but I've yet to see that in real code.

It would break some of my code which hashes on a pointer.

/Peter


Having C++/CLI as an example, it separates native pointers for native
types from managed pointers (named "handles") for managed types.
 
I

Ioannis Vranos

Ioannis said:
peter said:
(e-mail address removed)>, (e-mail address removed)
says...

[ ... ]

Yes. In practice, the C++ committee is at a juncture.
Independantly of any technical considerations, if the next
version of the standard doesn't support garbage collection and
threads, C++ is dead in the water---it will end up in the same
state as C, with a lot of older people used to it who continue
to use it, and argue in favor of it, because it's what they
know, but with less and less new applications being implemented
in it. (Alternatively, the major compiler vendors will simply
copy Microsoft, implement CLI, and call it C++. And the ISO
standard becomes irrelevant. And that's not a scenario I want
to see.)
N2287 attempts (but IMO, mostly fails) to do that. Truly supporting
garbage collection is, IMO, extraordinarily difficult. The problem is
that garbage collection is intended to have no externally visible effect
on the program. Since the standard's requirements are written in terms
of externally visible effects, actually requiring garbage collection is
essentially impossible. The closest N2287 comes is a non-normative note:

[Note: For garbage collected programs, a high quality hosted implemen-
tation should attempt to maximize the amount of unreachable memory it
reclaims. --end note ]

N2287 _does_ contain various ancillary requirements, such as for library
functions to control garbage collection, but in the end none of it
guarantees much of anything, since turning garbage collection on does
nothing more than enable the possibility of the implementation following
the advice of a non-normative note.

I don't think the future of C++ depends particularly heavily on garbage
collection, but I do think that if garbage collection is to be added,
there should at least be an attempt at doing it reasonably well. If
we're going to make it undefined behavior to do the things that can/will
break garbage collection, I think we should impose the (extremely few)
added restrictions necessary to allow an implementation to use a _good_
garbage collector.

It appears to me that this requires only one additional restriction:
that the program not depend in any way on the bit patterns stored in
pointers, such as hashing a pointer and later assuming that a pointer to
the same data will necessarily hash to the same value. We should also
make it undefined behavior to take a pointer value, store it into a non-
pointer type, and convert it back to a pointer, and then dereference the
result. In fact, I'm not sure that's really guaranteed to work now
(since there may not be any other type capable of holding a pointer
value) -- but I think it should be made explicit that it produces
undefined behavior. At the same time, pointers would retain their
original ordering (e.g. with an array, or as defined by std::less for
pointers to independent objects).

This restriction allows a great deal more flexibility in the design of
the collector itself, while imposing only a minimal burden on the
programmer. The burden is so minimal, in fact, that every piece of code
I've found that meets the requirements in N2287 also meets this
requirement, more or less by accident. As mentioned above, hashing a
pointer wouldn't, but I've yet to see that in real code.

It would break some of my code which hashes on a pointer.

/Peter


Having C++/CLI as an example, it separates native pointers for native
types from managed pointers (named "handles") for managed types.


Essentially, I think garbage collection is a "paradigm" itself, and must
be treated as ushc by ISO C++, that is to be provided separately, and to
be able to be intermixed with the rest of C++ paradigms, in the style of
C++/CLI.
 
I

Ioannis Vranos

Actually it looks like I was right, C++/CLI and CLI have become ISO
standards in addition to ECMA standards too.


Here is an interesting link about the rationale of C++/CLI that I think
is a "must" read for all.

I remind you that CLI is the standard for a type of a Virtual Machine
(examples are .NET, Mono), and C++/CLI is a standard that makes it
possible for C++ to take advantage all the facilities of this type of VM.

It keeps the notion of native code and managed code separate, while it
allows them to be intermixed at the same time.


The link:

http://www.gotw.ca/publications/C++CLIRationale.pdf
 
J

James Kanze

(e-mail address removed)>, (e-mail address removed)
says...
[ ... ]
Yes. In practice, the C++ committee is at a juncture.
Independantly of any technical considerations, if the next
version of the standard doesn't support garbage collection and
threads, C++ is dead in the water---it will end up in the same
state as C, with a lot of older people used to it who continue
to use it, and argue in favor of it, because it's what they
know, but with less and less new applications being implemented
in it. (Alternatively, the major compiler vendors will simply
copy Microsoft, implement CLI, and call it C++. And the ISO
standard becomes irrelevant. And that's not a scenario I want
to see.)
N2287 attempts (but IMO, mostly fails) to do that. Truly supporting
garbage collection is, IMO, extraordinarily difficult. The problem is
that garbage collection is intended to have no externally visible effect
on the program. Since the standard's requirements are written in terms
of externally visible effects, actually requiring garbage collection is
essentially impossible. The closest N2287 comes is a non-normative note:
[Note: For garbage collected programs, a high quality hosted implemen-
tation should attempt to maximize the amount of unreachable memory it
reclaims. ?end note ]

That's a general problem in the standard. The standard doesn't
say when memory released by the operator delete() function will be
reused (if ever) either, and formally:
void operator delete( void* ){}
is fully conforming. The standard does create certain
expectations, however, as to what a quality implementation will
try to do. Expectations which an intelligent reader will
modulate according to context; one certainly doesn't expect the
same things from an implementation on a small embedded processor
as from an implementation on a general purpose machine.

I think it was Steve Clamage who once said that a standard can't
require an implementation to be usable. We count on the
standard, but we also count on a lot more.
N2287 _does_ contain various ancillary requirements, such as
for library functions to control garbage collection, but in
the end none of it guarantees much of anything, since turning
garbage collection on does nothing more than enable the
possibility of the implementation following the advice of a
non-normative note.

A non-normative note still creates expectations with regards to
quality of implementation.
I don't think the future of C++ depends particularly heavily
on garbage collection,

Technically, I think we probably can live without it, although
it seems stupid to do so. I think that non-technical issues
mean that without threads and garbage collection, the language
is doomed to a slow death, much like C today.
but I do think that if garbage collection is to be added,
there should at least be an attempt at doing it reasonably
well. If we're going to make it undefined behavior to do the
things that can/will break garbage collection, I think we
should impose the (extremely few) added restrictions necessary
to allow an implementation to use a _good_ garbage collector.

What do you mean by a _good_ garbage collector? Practically
speaking, the presense of undiscriminated unions means that
perfect garbage collection is probably not in the cards.
(Formally speaking, accessing anything but the last written
member of a union is undefined behavior, and the standard allows
an implementation to maintain a hidden discriminator. In
practice, any implementation which actually did this would break
so much code as to be inviable.) But there are mostly accurate
collections which are used with C++, see for example
http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-88-2.pdf.
It appears to me that this requires only one additional
restriction: that the program not depend in any way on the bit
patterns stored in pointers, such as hashing a pointer and
later assuming that a pointer to the same data will
necessarily hash to the same value.

That's not guaranteed today, and I've used implementations where
you had to take particular precautions when hashing a pointer,
because different pointers to the same data could have different
bit patterns. (Think of 8086 compilers in model huge, which
only normalized a pointer when necessary.)
We should also make it undefined behavior to take a pointer
value, store it into a non-pointer type, and convert it back
to a pointer, and then dereference the result. In fact, I'm
not sure that's really guaranteed to work now (since there may
not be any other type capable of holding a pointer value) --
but I think it should be made explicit that it produces
undefined behavior. At the same time, pointers would retain
their original ordering (e.g. with an array, or as defined by
std::less for pointers to independent objects).

It's guaranteed to work today, if there is a sufficiently large
integral type. It does mean that a conservative collector is
required. Or a "mostly-accurate" one---the mostly accurate
collectors identify cases where this occurs, and treat them
conseratively, while treating the rest accurately (including
copying, in some cases).
This restriction allows a great deal more flexibility in the
design of the collector itself, while imposing only a minimal
burden on the programmer. The burden is so minimal, in fact,
that every piece of code I've found that meets the
requirements in N2287 also meets this requirement, more or
less by accident. As mentioned above, hashing a pointer
wouldn't, but I've yet to see that in real code.

That's been my experience as well. In practice, every piece of
real code I've actually encountered would work with a
mostly-accurate collector---the only things that would cause a
real problem with a fully accurate collector were unions, and
all of the unions with pointer types I've actually seen do obey
the formal rules, and would continue to work with a "hidden"
discrimintator.

(On another note: I think I'll write up a proposal real quick
for a standard hash function for pointers, since it's something
that a user can't write in an architecture independent manner.)
 
P

Pete Becker

(On another note: I think I'll write up a proposal real quick
for a standard hash function for pointers, since it's something
that a user can't write in an architecture independent manner.)

There's already one in C++0x. The template std::hash has a
specialization for std::hash<T*>, which gives you a callable type.
 
P

Pete Becker

Actually it looks like I was right, C++/CLI and CLI have become ISO
standards in addition to ECMA standards too.

CLI is an ISO standard. There is no ISO binding of C++ to CLI.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top