SDL-widgets GUI toolkit, new version

These days I write mostly in C, and use C++ whenever the project benefits from
being more completely object oriented. C++ or C# tend to be overkill for some
projects, especially embedded systems work.

I use C++ over C just about all the time, exception made of the most
hardcore embedded situations requiring XIP (gcc still has some bugs
that make it add a “constructor” to global instances of structs in
some cases where it is completely unjustified, might be fixed now).
You might want to “-fno-rtti -fno-exceptions”, you might want to avoid
templates, maybe even avoid virtual methods, in fact, it might look
exactly like C code, but just having the extra safety will save you
time, I guarantee it (in a way, just consider “-x c++” the same way
you’d consider “-Wall”).

For a demo (all of those come from finding them in real code, in the
real world), put the following code into foo.c, compile it once with
"gcc -c foo.c", and once with “gcc -x c++ -c foo.c” (I didn’t even
demonstrate the silent upgrading of (safe) static_cast to (dangerous)
reinterpret_cast with C-style casts, heh!):

// Just some setup…
struct Foo_;
struct Bar_;
struct Baz_;
typedef struct Foo_ Foo;
typedef struct Bar_ Bar;
typedef struct Baz_ Baz;
enum Safety {
SFT_LOW,
SFT_MED,
SFT_HIGH,
};

Bar* somefunc();
void someotherfunc(Baz*);

void myfunc()
{
Foo* blah = somefunc(42); // TWO bugs!
someotherfunc(blah); // bug
void* blah2 = blah; // ok, that’s fine
someotherfunc(blah2); // bug
enum Safety level = 42; // bug
}On Mon, Feb 16, 2009 at 2:26 PM, Jeff Post <j_post at pacbell.net> wrote:

Although some people do have a hard time wrapping their heads around
thinking recursively, which is something you have to do in ML.On Mon, Feb 16, 2009 at 3:38 PM, Donny Viszneki <@Donny_Viszneki> wrote:

On Mon, Feb 16, 2009 at 2:26 PM, Jeff Post <j_post at pacbell.net> wrote:

To have cleaner, safer, and more easily understood code. I wrote a lot of
object oriented C code both before and after C++ became available. It wasn’t
fully OO, just enough to make the code as robust as I wanted it to be.

some
programming languages and SDKs are very complex, convoluted, or
difficult to understand, but I don’t think anyone would argue that is
the case when comparing ML to C (if anything, C is the more convoluted
one, due to things like side-effects, type casts, and pointer
arithmetic.)


http://codebad.com/

Although some people do have a hard time wrapping their heads around
thinking recursively, which is something you have to do in ML.

Man, no tail-calls in C/C++, it’s a crying shame…On Mon, Feb 16, 2009 at 3:41 PM, Donny Viszneki <donny.viszneki at gmail.com> wrote:


http://pphaneuf.livejournal.com/

Yeah, why is that? With the exception of destructor semantics (only
relevant to C++) I can’t figure out why a C/C++ compiler would have a
hard time implementing tail call optimization.On Mon, Feb 16, 2009 at 3:43 PM, Pierre Phaneuf wrote:

Man, no tail-calls in C/C++, it’s a crying shame…


http://codebad.com/

Yeah, why is that? With the exception of destructor semantics (only
relevant to C++) I can’t figure out why a C/C++ compiler would have a
hard time implementing tail call optimization.

There’s a bunch of restrictions due to the calling conventions (caller
allocs/deallocs space on the stack, for example), so they just
wouldn’t be all that useful (being only able to call functions with no
arguments, for example).On Mon, Feb 16, 2009 at 3:44 PM, Donny Viszneki <donny.viszneki at gmail.com> wrote:


http://pphaneuf.livejournal.com/

I guess you would need two run-time implementations of the function so
that you could safely violate calling conventions within the bulk of
the recursive function’s call graph… or… is there any good reason
you couldn’t have a special “tail call proxy function” that would act
as an invocation gateway for any function that didn’t know it had to
use a special tail call optimization calling convention?On Mon, Feb 16, 2009 at 3:48 PM, Pierre Phaneuf wrote:

On Mon, Feb 16, 2009 at 3:44 PM, Donny Viszneki <@Donny_Viszneki> wrote:

Yeah, why is that? With the exception of destructor semantics (only
relevant to C++) I can’t figure out why a C/C++ compiler would have a
hard time implementing tail call optimization.

There’s a bunch of restrictions due to the calling conventions (caller
allocs/deallocs space on the stack, for example), so they just
wouldn’t be all that useful (being only able to call functions with no
arguments, for example).


http://codebad.com/

That’s not pedantry. I don’t know what that is, but if you believe
that is a valid argument for any reason, how exactly do you justify
not writing your software as machine code bit by bit?

Please, stop this thread right now. :slight_smile:

Thanks!
-Sam Lantinga, Founder and President, Galaxy Gameworks LLC

That’s not pedantry. I don’t know what that is, but if you believe
that is a valid argument for any reason, how exactly do you justify
not writing your software as machine code bit by bit?

If you choose to cook your own steak instead of eating at a restaurant, how
exactly do you justify not killing the cow yourself?

Sigh

I believe doing more things “by hand” neither makes your project
cleaner, nor safer, nor necessarily more easily understood.

OOP is a paradigm. It does not depend on the language, except for ease of
implementation. Everything you code is “by hand” unless you can input code
without a keyboard.

That said, it is easier to write OO using a language designed to take much
of the burden off your shoulders. But you end up with slower, more bloated
executables. Many times that’s not an issue; sometimes it’s very much an
issue.

It’s the ease of implementation that gets most people in trouble with C++.
They don’t think through, or don’t know about, what’s going on “under the
hood” in C++ and tell the compiler to do things they didn’t intend to happen.

(if anything, C is the more convoluted
one, due to things like side-effects, type casts, and pointer
arithmetic.)

It’s the responsibility of a professional programmer to not make newbie
mistakes. The mistakes newbies can make with C++ or C# are generally much
more disastrous than the mistakes one can make in C. And usually more
difficult to debug. YMMV.

I agree, I enjoy using C more than C++, but only because of how many
times I’ve been stung by the vile temptress of template programming!

One of many traps in C++ for the unwary :wink:

JeffOn Monday 16 February 2009 12:38, Donny Viszneki wrote:

I’m sorry to disagree with you. The difference is between “compile-time
typechecking” and “run-time typechecking”. The former can only be done
in a OO language featuring function-overloading and virtual functions.

I thought that Objective-C was an object oriented language. Heavily
relying on Smalltalk, the facther of the OO languages. Both of them
are based on run-type type checking, so much so that in Smalltalk even an
integer is an object. C++ might be more efficient than Objective-C
(although I am not absolutely sure), but Objective-C is as object oriented
as they get. It doesn’t have virtual functions (although it has protocols
and a few other bits that provide pretty much the same functionality)
but it can deal with remote objects, for example. You can ask the
compiler to do compile time type checks if efficiency is a concern at a
given place of the program, but run-time resolution is the core feature.

So, run-time typechecking is just as object oriented as compile-time. In
fact, even more. In Objective-C you can send a message (invoke a member
function) to an object that you’ve never heard about. As long as it
implements the method, it will respond to it. Most importantly, you can
ask every object what they are, if they implement a method or not and so
on. Added bonus is that Objective-C adds maybe 10 keywords to normal C,
with absolutely minimum extra syntax. Any ANSI C program is also a valid
Objective-C program (unlike C -> C++) and Objective-C can be fully
described to a C programmer on about 20 pages. Now try that with C++…
:slight_smile:

And about that translating to C by the first C++ compilers … During the
translation a lot of extra variables and macro’s where inserted, e.g.
in order to generate unique function names for each method and function.
It is not completely impossible to do this by hand of course, but why
would you?

Because then you know what’s there exactly. Some people like to know
what’s going on. By the way, you do not need to have unique function
names. Consider write() that works quite fine on the serial port object,
any file object, any raw block device object, any pipe object, a network
connection object and pretty much on any object that can receive user
data. It is not that bad to use write( fd … ) instead of fd.write(…).

In C to a degree you can be more object-oriented than in C++. You can have
opaque data types that really hide the implementation details from the
user while in C++ you must expose your class structure even if the user
will never need to know its internal details or even its size.

Zoltan

I disagree with nearly all of what you have said when you say “in c++” or the like. I would urge you to take your argument one thing at a time to a c++ coder community and see what comes out. Some things are obscure because people don’t like to do it or teach it can be done that way.
---- zoltan at bendor.com.au wrote:=============

I’m sorry to disagree with you. The difference is between “compile-time
typechecking” and “run-time typechecking”. The former can only be done
in a OO language featuring function-overloading and virtual functions.

I thought that Objective-C was an object oriented language. Heavily
relying on Smalltalk, the facther of the OO languages. Both of them
are based on run-type type checking, so much so that in Smalltalk even an
integer is an object. C++ might be more efficient than Objective-C
(although I am not absolutely sure), but Objective-C is as object oriented
as they get. It doesn’t have virtual functions (although it has protocols
and a few other bits that provide pretty much the same functionality)
but it can deal with remote objects, for example. You can ask the
compiler to do compile time type checks if efficiency is a concern at a
given place of the program, but run-time resolution is the core feature.

So, run-time typechecking is just as object oriented as compile-time. In
fact, even more. In Objective-C you can send a message (invoke a member
function) to an object that you’ve never heard about. As long as it
implements the method, it will respond to it. Most importantly, you can
ask every object what they are, if they implement a method or not and so
on. Added bonus is that Objective-C adds maybe 10 keywords to normal C,
with absolutely minimum extra syntax. Any ANSI C program is also a valid
Objective-C program (unlike C -> C++) and Objective-C can be fully
described to a C programmer on about 20 pages. Now try that with C++…
:slight_smile:

And about that translating to C by the first C++ compilers … During the
translation a lot of extra variables and macro’s where inserted, e.g.
in order to generate unique function names for each method and function.
It is not completely impossible to do this by hand of course, but why
would you?

Because then you know what’s there exactly. Some people like to know
what’s going on. By the way, you do not need to have unique function
names. Consider write() that works quite fine on the serial port object,
any file object, any raw block device object, any pipe object, a network
connection object and pretty much on any object that can receive user
data. It is not that bad to use write( fd … ) instead of fd.write(…).

In C to a degree you can be more object-oriented than in C++. You can have
opaque data types that really hide the implementation details from the
user while in C++ you must expose your class structure even if the user
will never need to know its internal details or even its size.

Zoltan


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

Sorry that I don’t remember enough of the thread context to address
most of what you said Jeff, but one part I would really like to hear
supporting examples for:On Mon, Feb 16, 2009 at 5:30 PM, Jeff Post <j_post at pacbell.net> wrote:

On Monday 16 February 2009 12:38, Donny Viszneki wrote:

(if anything, C is the more convoluted
one, due to things like side-effects, type casts, and pointer
arithmetic.)

It’s the responsibility of a professional programmer to not make newbie
mistakes. The mistakes newbies can make with C++ or C# are generally much
more disastrous than the mistakes one can make in C. And usually more
difficult to debug. YMMV.

I would love to hear what bugs crop up in C++ and C# which you
describe as being more “disastrous” and “difficult to debug” than
those that tend to crop up in C.


http://codebad.com/

I disagree with nearly all of what you have said when you say “in
c++” or the like. I would urge you to take your argument one thing at
a time to a c++ coder community and see what comes out. Some things
are obscure because people don’t like to do it or teach it can be
done that way. ---- @Zoltan_Kocsi wrote:

Um, which bit do you disagree with? That Smalltalk and Obj-C are object
oriented, or that Obj-C is much simpler to learn than C++ or that with
C++ you have a lot less knowledge of exactly what functions are called
and when than in C or that in C you can write opaque data types while a
C++ class (by definition) can not hide the actual content of the class?

It wasn’t a criticism of C++ as such (although, I admit, I do not like
it but that’s irrelevant, really), it was a statement that compile-time
type checking is not a necessary feature in an object oriented language.

In addition, especially in embedded systems you really want to know
what’s being executed and when. In C that’s straightforward, in C++,
when the compiler generates a lot of code, you can’t be that sure.

As per the opaque data types, it is self-evident, I think.

Regards,

ZoltanOn Thu, 26 Feb 2009 20:16:58 -0500 wrote:

=============

I’m sorry to disagree with you. The difference is between
"compile-time typechecking" and “run-time typechecking”. The former
can only be done in a OO language featuring function-overloading
and virtual functions.

I thought that Objective-C was an object oriented language. Heavily
relying on Smalltalk, the facther of the OO languages. Both of them
are based on run-type type checking, so much so that in Smalltalk
even an integer is an object. C++ might be more efficient than
Objective-C (although I am not absolutely sure), but Objective-C is
as object oriented as they get. It doesn’t have virtual functions
(although it has protocols and a few other bits that provide pretty
much the same functionality) but it can deal with remote objects,
for example. You can ask the compiler to do compile time type checks
if efficiency is a concern at a given place of the program, but
run-time resolution is the core feature.

So, run-time typechecking is just as object oriented as compile-time.
In fact, even more. In Objective-C you can send a message (invoke a
member function) to an object that you’ve never heard about. As long
as it implements the method, it will respond to it. Most importantly,
you can ask every object what they are, if they implement a method or
not and so on. Added bonus is that Objective-C adds maybe 10 keywords
to normal C, with absolutely minimum extra syntax. Any ANSI C program
is also a valid Objective-C program (unlike C -> C++) and Objective-C
can be fully described to a C programmer on about 20 pages. Now try
that with C++… :slight_smile:

And about that translating to C by the first C++ compilers …
During the translation a lot of extra variables and macro’s where
inserted, e.g. in order to generate unique function names for each
method and function. It is not completely impossible to do this by
hand of course, but why would you?

Because then you know what’s there exactly. Some people like to know
what’s going on. By the way, you do not need to have unique function
names. Consider write() that works quite fine on the serial port
object, any file object, any raw block device object, any pipe
object, a network connection object and pretty much on any object
that can receive user data. It is not that bad to use write( fd … )
instead of fd.write(…).

In C to a degree you can be more object-oriented than in C++. You can
have opaque data types that really hide the implementation details
from the user while in C++ you must expose your class structure even
if the user will never need to know its internal details or even its
size.

Zoltan


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