Rewrite input system for hot-plugging

Damage control time…

if you’re under the age of 13 please stop reading what mason writes :stuck_out_tongue:

It is when you consider the alternative. ?How often do you write a
constructor and initialize any member to any constant value other than
zero/NULL? ?I’ve seen it a very few times, and those usually have to
do with enumerated types. ?But most of the time you either initialize
things to zero or to the result of some function or constructor.

If you were only talking about references/pointers, I’m behind you
100% on the initialization value argument.

In fact, C++ is also behind you 100%. That’s why references were added
to C++ so that you don’t have to use pointers which might have
arbitrary garbage values. (Personally I feel they’re a little too
restrictive, but it sounds like you care more about having your values
initialized to something useful.)

Your assertion that most initialization values should be zero or NULL
is completely f’n retarded. It is critical to initialize values
yourself.

The reason you need RAII when you don’t zero out the memory is because
if something goes wrong during object construction and you throw an
exception, the destructor has no way of telling how far along the
construction process got before bailing out, so it doesn’t know which
sub-objects are safe to destroy and which aren’t. ?If the memory had been
zeroed out first, you could call Free on everything safely.

Sure, in Imagination Land where most of the Resources you’re Acquiring
only exist inside in-process memory, and aren’t things that exist in
other processes, in the kernel, on other systems, or in meatspace (try
telling the engineers that write systems at a nuclear power facility
they can’t use RAII because all their plutonium should have been
initialized to zeros.)

Take this off list.


http://codebad.com/


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

LOL…

long ago at a company now renamed… It was called Sperry Univac at
the time. They made machines with 36 bit words and a 6 bit character
set and I worked there writing software to sell to customers. (I
helped write the best damn Cobol VM ever to run in 16 kilobytes on an
8080!) Anyway… the word UNIVAC fit nicely in each word on one of
these odd beasts and that has a lot to do with the rest of the story.

The default compilers allocators and such (this is in the '70s long
before some of you were born and years before I ever heard of this
strange thing called “C”) all initialized memory to 0. Lots of
statistics collected from the '40s on showed that the most common bug
was to fail for initialize allocated memory. So, the machines we used
to develop on inside the company had this weird little hack that was
not in customers machines. Our machines always initialized every bit
off memory to “UNIVAC”. Doing that made it very easy recognize
uninitialized memory and dramatically reduced the number of bugs found
by customers.

If I had my way all newly allocated memory would be initialized with
the pattern “DIP*SHIT” nicely aligned on 64 bit boundaries.

Bob Pendleton

P.S.

At least I didn’t tell you the story of how to make the Unisuck 1108
Fortran runtime print the message “OHHELL” is a bad value as the
result of evaluting a format statement in a program that does not
contain that string. Lexer bugs are fun…On Tue, Sep 8, 2009 at 10:30 AM, Donny Viszneki <donny.viszneki at gmail.com> wrote:

On Tue, Sep 8, 2009 at 11:13 AM, Mason Wheeler wrote:


±----------------------------------------------------------

blink
Did Bob just agree with me on a language-features topic?
sweatdrop The end is nigh!>----- Original Message ----

From: Bob Pendleton
Subject: Re: [SDL] Rewrite input system for hot-plugging

LOL…

long ago at a company now renamed… It was called Sperry Univac at
the time. They made machines with 36 bit words and a 6 bit character
set and I worked there writing software to sell to customers. (I
helped write the best damn Cobol VM ever to run in 16 kilobytes on an
8080!) Anyway… the word UNIVAC fit nicely in each word on one of
these odd beasts and that has a lot to do with the rest of the story.

The default compilers allocators and such (this is in the '70s long
before some of you were born and years before I ever heard of this
strange thing called “C”) all initialized memory to 0. Lots of
statistics collected from the '40s on showed that the most common bug
was to fail for initialize allocated memory. So, the machines we used
to develop on inside the company had this weird little hack that was
not in customers machines. Our machines always initialized every bit
off memory to “UNIVAC”. Doing that made it very easy recognize
uninitialized memory and dramatically reduced the number of bugs found
by customers.

If I had my way all newly allocated memory would be initialized with
the pattern “DIP*SHIT” nicely aligned on 64 bit boundaries.

Bob Pendleton

I was kind of fond of 0xdeadbeef. Caught lots of errors :slight_smile:

JeffOn Thursday 10 September 2009 11:56, Bob Pendleton wrote:

If I had my way all newly allocated memory would be initialized with
the pattern “DIP*SHIT” nicely aligned on 64 bit boundaries.

blink
Did Bob just agree with me on a language-features topic?
sweatdrop The end is nigh!

I lost track of who was for automatic initialization and who wasn’t
and what it should be initialized to. I just like the idea of making
sure that use of uninitialized values results in easily identifiable
errors. And, to enforce that I like the idea of initializing values to
an easily recognized and almost always wrong value.

BTW, when did “RAII” become a “pattern”? It has always been a
requirement for creating working code.

Bob PendletonOn Thu, Sep 10, 2009 at 2:43 PM, Mason Wheeler wrote:

----- Original Message ----

From: Bob Pendleton <@Bob_Pendleton>
Subject: Re: [SDL] Rewrite input system for hot-plugging

LOL…

long ago at a company now renamed… It was called Sperry Univac at
the time. They made machines with 36 bit words and a 6 bit character
set and I worked there writing software to sell to customers. (I
helped write the best damn Cobol VM ever to run in 16 kilobytes on an
8080!) Anyway… the word UNIVAC fit nicely in each word on one of
these odd beasts and that has a lot to do with the rest of the story.

The default compilers allocators and such (this is in the '70s long
before some of you were born and years before I ever heard of this
strange thing called “C”) all initialized memory to 0. Lots of
statistics collected from the '40s on showed that the most common bug
was to fail for initialize allocated memory. So, the machines we used
to develop on inside the company had this weird little hack that was
not in customers machines. Our machines always initialized every bit
off memory to “UNIVAC”. Doing that made it very easy recognize
uninitialized memory and dramatically reduced the number of bugs found
by customers.

If I had my way all newly allocated memory would be initialized with
the pattern “DIP*SHIT” nicely aligned on 64 bit boundaries.

Bob Pendleton


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


±----------------------------------------------------------

BTW, when did “RAII” become a “pattern”? It has always been a
requirement for creating working code.

Only under C+±style object semantics. If your objects’ memory
gets zeroed before the constructor is called, you can’t allocate
objects on the stack, and you have a try…finally construct available
(I forgot that one the first time around), the problems the RAII
pattern solves don’t exist. Unfortunately, C++ fails on all three
counts.>----- Original Message ----

From: Bob Pendleton
Subject: Re: [SDL] Rewrite input system for hot-plugging

2009/9/10 Bob Pendleton :

BTW, when did “RAII” become a “pattern”? It has always been a
requirement for creating working code.

I think RAII is specifically when it happens automatically, like
calling the constructor from new.

BTW, when did “RAII” become a “pattern”? It has always been a
requirement for creating working code.

Only under C+±style object semantics. ?If your objects’ memory
gets zeroed before the constructor is called, you can’t allocate
objects on the stack,

You lost me there. Why do you believe that? All you need to be able to
zero before calling the constructor would be to know how large the
class is and where it will reside on the stack. And, you have to know
the stack base and the size whether you auto initialize it or not.

Bob PendletonOn Thu, Sep 10, 2009 at 5:01 PM, Mason Wheeler wrote:

----- Original Message ----
From: Bob Pendleton <@Bob_Pendleton>
Subject: Re: [SDL] Rewrite input system for hot-plugging

and you have a try…finally construct available
(I forgot that one the first time around), the problems the RAII
pattern solves don’t exist. ?Unfortunately, C++ fails on all three
counts.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


±----------------------------------------------------------

Only under C+±style object semantics. If your objects’ memory
gets zeroed before the constructor is called, you can’t allocate
objects on the stack,

You lost me there. Why do you believe that? All you need to be able to
zero before calling the constructor would be to know how large the
class is and where it will reside on the stack. And, you have to know
the stack base and the size whether you auto initialize it or not.

Sorry, that was supposed to be a list. If you zero out your memory,
and you can’t allocate objects on the stack (as opposed to C++,
in which you can), and you have a try…finally construct available,
then…>----- Original Message ----

From: Bob Pendleton
Subject: Re: [SDL] Rewrite input system for hot-plugging
On Thu, Sep 10, 2009 at 5:01 PM, Mason Wheeler <@Mason_Wheeler> wrote:

----- Original Message ----

Mason Wheeler wrote:>> ----- Original Message ----

From: Bob Pendleton
Subject: Re: [SDL] Rewrite input system for hot-plugging

BTW, when did “RAII” become a “pattern”? It has always been a
requirement for creating working code.

Only under C+±style object semantics. If your objects’ memory
gets zeroed before the constructor is called, you can’t allocate
objects on the stack, and you have a try…finally construct available
(I forgot that one the first time around), the problems the RAII
pattern solves don’t exist. Unfortunately, C++ fails on all three
counts.

By the same reasoning, if you have ‘free’, then the problem that garbage
collection solves doesn’t exist. Let’s all go back to managing our
resources manually.

try/finally is a shitty workaround for lack of RAII. You can forget to
use it, and even if you use it, it clutters up your code. RAII
automates the whole pattern so you don’t have to waste time and space
writing the same resource management code over and over again.


Rainer Deyke - rainerd at eldwood.com

Mason Wheeler wrote:

BTW, when did “RAII” become a “pattern”? It has always been a
requirement for creating working code.

Only under C+±style object semantics. If your objects’ memory
gets zeroed before the constructor is called, you can’t allocate
objects on the stack, and you have a try…finally construct available
(I forgot that one the first time around), the problems the RAII
pattern solves don’t exist. Unfortunately, C++ fails on all three
counts.

By the same reasoning, if you have ‘free’, then the problem that garbage
collection solves doesn’t exist. Let’s all go back to managing our
resources manually.

Well, seeing as how neither of the problems that garbage collection
purports to solve are actually solved by GC, and one of them is actually
made worse, and it introduces new problems, I’d have to agree with
your statement without any of the irony you seem to intend.

try/finally is a shitty workaround for lack of RAII. You can forget to
use it, and even if you use it, it clutters up your code. RAII
automates the whole pattern so you don’t have to waste time and space
writing the same resource management code over and over again.

Gotta turn that one on its head. RAII is a horrible workaround for lack
of a try/finally construct, since it gets used in plenty of other cases
besides resource management. For example:

MyDataset.DisableControls; //prevent linked controls from updating every time we change data
try
//a whole bunch of updates here
finally
MyDataset.EnableControls;
end;

How would you do that in C++?>----- Original Message ----

From: Rainer Deyke
Subject: Re: [SDL] Rewrite input system for hot-plugging

----- Original Message ----
From: Bob Pendleton
Subject: Re: [SDL] Rewrite input system for hot-plugging

Still, while zero is a common default, its not always appropriate. I
prefer to have classes with invariants where NULL isn’t an option. For
example, a Surface wrapper will either hold a valid handle to a
surface when its constructor ends, or will throw an exception.
Removing the idea of dealing with a “null” surface simplifies the
class, both in interface and implementation. This is but one b

Sorry, that was supposed to be a list. ?If you zero out your memory,
and you can’t allocate objects on the stack (as opposed to C++,
in which you can), and you have a try…finally construct available,
then…

Simply:

class TemporaryControlDisabler : noncopyable
{
TemporaryControlDisabler(DataSet &set) : set(&set)
{
set.DisableControls();
}

~ TemporaryControlDisabler()
{
    set.EnableControls();
}

private: DataSet *set;
};

void foo(DataSet &set)
{
TemporaryControlDisabler disabler(set);

// if we return here, or an exception is thrown, the controls will

be re-enabled
}

You’ll have to excuse the ridiculous class name, I’m tired and sick
and want to go to bed. =)On Thu, Sep 10, 2009 at 11:40 PM, Mason Wheeler wrote:

MyDataset.DisableControls; //prevent linked controls from updating every time we change data
try
//a whole bunch of updates here
finally
MyDataset.EnableControls;
end;

How would you do that in C++?

Simply:

class TemporaryControlDisabler : noncopyable
{
TemporaryControlDisabler(DataSet &set) : set(&set)
{
set.DisableControls();
}

~ TemporaryControlDisabler()
{
set.EnableControls();
}
private: DataSet *set;
};

void foo(DataSet &set)
{
TemporaryControlDisabler disabler(set);

// if we return here, or an exception is thrown, the controls will
be re-enabled
}

You’ll have to excuse the ridiculous class name, I’m tired and sick
and want to go to bed. =)

MyDataset.DisableControls; //prevent linked controls from updating every time we change data
try
//a whole bunch of updates here
finally
MyDataset.EnableControls;
end;

How would you do that in C++?

Yeah, I figured that’s how you’d end up having to do it. Create
an entirely new class and instantiate an object to set up a
situation so that RAII can take care of something you should
be able to handle with a simple try…finally block.>----- Original Message ----

From: Brian <brian.ripoff at gmail.com>
Subject: Re: [SDL] Rewrite input system for hot-plugging

Mason Wheeler wrote:

By the same reasoning, if you have ‘free’, then the problem that garbage
collection solves doesn’t exist. Let’s all go back to managing our
resources manually.

Well, seeing as how neither of the problems that garbage collection
purports to solve are actually solved by GC, and one of them is actually
made worse, and it introduces new problems, I’d have to agree with
your statement without any of the irony you seem to intend.

I’m not really a fan of garbage collection at all, but it’s silly to
claim that it doesn’t solve any problems. It certainly solves this problem:

void f() {
void *p = malloc(1024);
// More code
// Oops, forgot to free the memory I allocated.
}

The resource-management problems that garbage fails to solve are exactly
the problems that RAII /does/ solve, which is why I prefer C++ over
garbage-collected languages.

Gotta turn that one on its head. RAII is a horrible workaround for lack
of a try/finally construct, since it gets used in plenty of other cases
besides resource management. For example:

MyDataset.DisableControls; //prevent linked controls from updating every time we change data
try
//a whole bunch of updates here
finally
MyDataset.EnableControls;
end;

How would you do that in C++?

The C++ version is superior:

DatasetControlsDisabler MyDatasetControlDisabler(MyDataset);
// a while bunch of updates here

Why? Because I just reduced 5 lines of code to 1. Because in the C++
version, you can’t forget to reenable the controls. Because
DatasetControlsDisabler is a reusable class that can be tested separately.

I’m not against try/finally at all. I also like the scope statements
from D. But in this case RAII is clearly the superior solution.>> ----- Original Message ----

From: Rainer Deyke
Subject: Re: [SDL] Rewrite input system for hot-plugging


Rainer Deyke - rainerd at eldwood.com

There are now 71 messages in this thread and the vast majority are off
topic, not only for the list, but even the original post. Perhaps
it’s time to start flaming each other directly instead of spamming
SDL.

Couldn’t agree more with it.On Fri, Sep 11, 2009 at 7:39 AM, Kenneth Bull wrote:

There are now 71 messages in this thread and the vast majority are off
topic, not only for the list, but even the original post. Perhaps
it’s time to start flaming each other directly instead of spamming
SDL.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Ah, I was enjoying it :(On Fri, Sep 11, 2009 at 3:10 AM, Paulo Pinto wrote:

Couldn’t agree more with it.

On Fri, Sep 11, 2009 at 7:39 AM, Kenneth Bull wrote:

There are now 71 messages in this thread and the vast majority are off
topic, not only for the list, but even the original post. ?Perhaps
it’s time to start flaming each other directly instead of spamming
SDL.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Mason Wheeler wrote:

Well, seeing as how neither of the problems that garbage collection
purports to solve are actually solved by GC, and one of them is actually
made worse, and it introduces new problems, I’d have to agree with
your statement without any of the irony you seem to intend.

I’m not really a fan of garbage collection at all, but it’s silly to
claim that it doesn’t solve any problems. It certainly solves this problem:

void f() {
void *p = malloc(1024);
// More code
// Oops, forgot to free the memory I allocated.
}

Are you sure about that? Is there any guarantee that P will ever be
collected, much less in a timely fashion? If you’re using a generational
garbage collector and there’s enough stuff happening in the “//More
code” section for a generational sweep to have come and gone,
relegating the still-valid P to gen 2, there’s a decent chance that it
won’t ever be collected before your program terminates unless
memory pressure requires it.

GC purports to solve two problems: Memory not getting freed when it’s
no longer needed (memory leaks) and memory getting freed before
it’s no longer needed (which causes double-free errors and other
memory corruption problems.) But there’s no GC I’m aware of that
frees memory when it’s no longer needed; they wait until some time
afterwards to run a sweep, in which they may or may not (and usually
don’t) catch everything. But what about the other problem, freeing
too early?

http://www.mozilla.org/security/announce/2009/mfsa2009-13.html
Hmm… nope, not fixed either.

And in fact, GC often makes memory leak issues even worse,
because it leads coders to think that the GC has them covered and
they don’t think about what they’re doing with their references and
leave them lying around in places they can’t be collected. (
http://cgi.cse.unsw.edu.au/~dons/blog/2008/05/16 gives a great
example.) In the end you still have to know how your GC works
and code around it so that it’ll collect things efficiently.

Hmm… sounds like we’re still managing memory manually, just
not freeing it manually. So as long as you’re still managing
memory manually, why not just free it yourself as soon as it’s
no longer needed, which a GC can’t do anyway?>----- Original Message ----

From: Rainer Deyke
Subject: Re: [SDL] Rewrite input system for hot-plugging

Mason Wheeler wrote:

Are you sure about that? Is there any guarantee that P will ever be
collected, much less in a timely fashion?

Who cares? Most memory allocators in most languages never release
"freed" memory back to the OS. Instead, they keep the memory around for
future allocation requests. GC does the same, it just delays the
calculation of which memory “freed” until it actually receives an
allocation request that it cannot otherwise fulfill.

http://www.mozilla.org/security/announce/2009/mfsa2009-13.html
Hmm… nope, not fixed either.

One bug in one GC in no way invalidates GC as a general strategy.

And in fact, GC often makes memory leak issues even worse,
because it leads coders to think that the GC has them covered and
they don’t think about what they’re doing with their references and
leave them lying around in places they can’t be collected. (
http://cgi.cse.unsw.edu.au/~dons/blog/2008/05/16 gives a great
example.) In the end you still have to know how your GC works
and code around it so that it’ll collect things efficiently.

GC automates many common cases. It doesn’t completely eliminate the
need to think.

Also, the types of memory leaks allowed by GC are typically less serious
than the leaks that GC prevents. You can have a chain of useless
uncollected data with GC, but the entire chain will be freed if the
pointer to the chain ever goes out of scope.

Hmm… sounds like we’re still managing memory manually, just
not freeing it manually. So as long as you’re still managing
memory manually, why not just free it yourself as soon as it’s
no longer needed, which a GC can’t do anyway?

Speed, for one thing. Copying GC is usually faster than manual memory
management schemes.–
Rainer Deyke - rainerd at eldwood.com

Rainer Deyke wrote:

Mason Wheeler wrote:

By the same reasoning, if you have ‘free’, then the problem that garbage
collection solves doesn’t exist. Let’s all go back to managing our
resources manually.

Well, seeing as how neither of the problems that garbage collection
purports to solve are actually solved by GC, and one of them is actually
made worse, and it introduces new problems, I’d have to agree with
your statement without any of the irony you seem to intend.

I’m not really a fan of garbage collection at all, but it’s silly to
claim that it doesn’t solve any problems. It certainly solves this problem:

void f() {
void *p = malloc(1024);
// More code
// Oops, forgot to free the memory I allocated.
}

The resource-management problems that garbage fails to solve are exactly
the problems that RAII /does/ solve, which is why I prefer C++ over
garbage-collected languages.

In the code you supply, GC seems to be delaying the discovery that the
programmer is incompetent.>>> ----- Original Message ----

From: Rainer Deyke
Subject: Re: [SDL] Rewrite input system for hot-plugging

“C++ tends to produce much larger binaries” is a myth. If you write
something using a bunch of STL or other template-heavy code, then
sure, you get big binaries. But attributing this to C++ is a mistake.

I skipped most of the C++ discussion, but let me just settle it:

There will be no C++ in SDL.

(Disclaimer: minus places we’ve been forced to use it, namely BeOS.)

There are several open source C++ wrappers for SDL, and more show up all
the time. I don’t have any interest in maintaining one, though.

I think PyGame is a good model there. We don’t maintain Python bindings,
but the PyGame people do a kickass job.

As for the input subsystem: we do occasionally get requests for
reading input without a window, but most people don’t need it, and it’s
problematic to implement at all on many platforms. With SDL 1.3’s
multiple window support, it’s even moreso.

I’m happy to entertain good ideas and patches, though, but I’d call it
low-priority.

If the existing code is unnecessarily nasty, though, I’m definitely not
against getting it cleaned up.

–ryan.