SDL 1.3 proposed conventions

I’m looking for general feedback here from experienced developers.
As always, please do not turn this into a flame war, or I will stop
soliciting feedback.

Thanks!

Here are some proposed conventions for the SDL 1.3 -> 2.0 rewrite:

API conventions:

SDL functions return a boolean value or a pointer value
SDL functions are prefixed with “SDL2_” … “SDL_” ?
SDL functions take a status pointer as the first argument
This status pointer can be 0, but no error information will be saved.

e.g.

bool SDL2_Init(SDL_status *status, Uint32 flags);
SDL_VideoMode *SDL2_FirstVideoMode(SDL_status *status, Uint32 flags);

If a function returns 0 or a NULL pointer, an error code or string
can be retrieved from the status object:

SDL_string *string;

switch (status->code) {
case SDL_OUTOFMEMORY:
/* Perform garbage collection and try again? */
break;
default:
string = SDL2_GetStatusString(status);
ShowMessage(“Operation Failed”, string);
break;
}

SDL_statuscode is an enumerated type that contains as many error
conditions as possible. These are organized into extendable blocks
so that individual drivers can add their own error codes.

Each function prototype will include a documentation section which
contains return value, parameters, and non-driver-specific error
conditions. It will also contain a brief note on thread-safety.
The documentation section is set off by /** so documentation tools
can parse it easily.

Coding conventions:

The SDL code is written in ANSI C using 4 space tabstops and spaces
liberally for code readability:

/**
SDL2_function - this is a useful function to do something

@param status
Standard SDL status information
@param param
A parameter of some type
@return a new object of some type

This function should be used when there is something special to be done.
You should watch out for X, Y, and Z, as they can surprise you.
How much useless documentation can I write for a fictional function?

Thread-safety: This function is completely thread-safe

@see SDL_status
**/
object *
SDL2_function(SDL_status status, int param)
{
/
This comment adds clarity to the code */
if ( internal_function(status) == failure )
handle_failure(status);
else
handle_success();

/*
 * Note that C++ style comments are not allowed by some compilers.
 * Also, keep the code formatted to 78 characters if possible.
 */
if ( (condition_one() == failure) ||
     (condition_two() == failure) ) {
    handle_failure(status);
} else {
    handle_success();
}
return new_object;

}

What do people think? Good? Bad? Ugly?
Again, this is for constructive feedback, so if you don’t have anything
nice to say about someone’s opinions, don’t say it!

See ya!
-Sam Lantinga, Lead Programmer, Loki Software, Inc.

SDL functions return a boolean value or a pointer value

Always? Is there no where that a Uint32 would be appropriate, or is this
thinking ahead to some bizarre embedded device that only allows certain
size return values? I’m just curious, mostly.

SDL functions are prefixed with “SDL2_” … “SDL_” ?

I personally would prefer leaving it as “SDL_” … let people link against
a 1.2 binary if they want 1.2 functionality.

SDL functions take a status pointer as the first argument
This status pointer can be 0, but no error information will be saved.

Is this an effort to make a thread safe alternative to SDL_GetError()? I
do like this.

Each function prototype will include a documentation section which
contains return value, parameters, and non-driver-specific error
conditions. It will also contain a brief note on thread-safety.
The documentation section is set off by /** so documentation tools
can parse it easily.

Nice.

Coding conventions:

The SDL code is written in ANSI C using 4 space tabstops and spaces
liberally for code readability:

Without starting the holy war ( :slight_smile: ), I’d personally beg for not using
tab characters at all, and just spaces (at indentions of four, if you
prefer). If nothing else, it verifies that the source will look consistent
in everyone’s editor, no matter what his individual tabstops are set to.
That’s just me, and that’s as far as I’ll defend it.

[in regards to coding style]
What do people think? Good? Bad? Ugly?

That’s just about my exact personal coding style, so I’m all for it.

–ryan.

API conventions:

SDL functions return a boolean value or a pointer value

“bool” isn’t strictly the same with all compiler versions,
just stick to “int” - or its equivalent SDL_status.

SDL functions are prefixed with “SDL2_” … “SDL_” ?

Prefix SDL_ is fine, using SDL2_ is not acutally needed,
just ensure that the same function-name is not going to
be defined with a different arg/ret-signature. If there’d
really be a needs, add the nextgeneration mark as a
suffix, e.g. InitEx or even Init2. The package is still
the same anyway, and as long as it is libSDL it should be
called that way. And there’s no need to add a nextgeneration
mark at each symbol, there are surely some things that can
be rescued, doesn’t it.

SDL functions take a status pointer as the first argument
This status pointer can be 0, but no error information will be saved.

The other way round, all functions return a status-code, and
if one needs a return-value, make that an indirekt return-arg.

e.g.

bool SDL2_Init(SDL_status *status, Uint32 flags);
SDL_VideoMode *SDL2_FirstVideoMode(SDL_status *status, Uint32 flags);

e.g.
SDL_status SDL_Init2 (Uint32 flags)
SDL_status SDL_FirstVideoMode(Uint32 flags, SDL_Videomode** mode);

[…]
SDL_statuscode is an enumerated type that contains as many error
conditions as possible. These are organized into extendable blocks
so that individual drivers can add their own error codes.

yes. Just a linked list to functions that may eventually
return static-text is all we need, no dynamic errorstringbuffer.

Each function prototype will include a documentation section which
contains return value, parameters, and non-driver-specific error
conditions. It will also contain a brief note on thread-safety.
The documentation section is set off by /** so documentation tools
can parse it easily.
javadoc-anystyle is pretty much common now.

Coding conventions:

The SDL code is written in ANSI C using 4 space tabstops and spaces
liberally for code readability:
make it an emacs-style at the end of the file, e.g.

/*

  • Local variables:
  • c-file-style: “stroustrup”
  • End:
    */

the emacs-modes are also understood by gnu’ indent program
to easily check conformance. I’d better not strictly enforce
it, there are good places to break them. And yes, pleeeeeasssse,
add a thread-safety marker to each function.

[…]

cheers,
– guido http://guidod.4t.com
31:GCS/E/S/P C++$++++ ULHS L++w- N++@ d(±) s+a- h.r(*@)>+++ y++ 5++X-

Guido Draheim wrote:

called that way. And there’s no need to add a nextgeneration
mark at each symbol, there are surely some things that can
be rescued, doesn’t it.
To keep a good set of function under the same name with
the same behaviour decreases the need to learn new things
and decreases the needs to change source code. Don’t break
knowledge and writtensoftware without need, not even for
TheCleanDesign - it’s just academic.

SDL functions return a boolean value or a pointer value
SDL functions take a status pointer as the first argument
This status pointer can be 0, but no error information will be
saved.

Is this change the result of a dissatisfaction with some GetLastError
type of mechanism??

Might I recommend some global structure instead of passing a pointer
for every call? (I can see that extra parameter getting tedious) Or
maybe an OpenGL-style “is everything peachy?” type of function? (I
guess that’s the same as GetLastError, except that you don’t use up
the return value of most functions for result/error…)

BTW, I think “bool” is the C++ version of C’s “BOOL”. I remember VC++
giving me a warning about something like that.

The SDL code is written in ANSI C using 4 space tabstops and spaces
liberally for code readability:

Sounds very good. The special format for the function prototype
comment is also a good idea.

/*
 * Note that C++ style comments are not allowed by some

compilers.

 * Also, keep the code formatted to 78 characters if possible.
 */

Also very good.

if ( (condition_one() == failure) ||
     (condition_two() == failure) ) {
    handle_failure(status);
} else {
    handle_success();
}
return new_object;

Personally I like to have the “{” on their seperate lines, but I’m
getting used to this format.

What do people think? Good? Bad? Ugly?

Good idea to poll the audience, let’s just hope it doesn’t turn into a
flame war.–

Olivier A. Dagenais - Software Architect and Developer

SDL functions take a status pointer as the first argument
This status pointer can be 0, but no error information will be saved.

You could introduce the concept of a context so you could have multiple SDL
contexts per application and have something like SDL_MakeCurrent and
SDL_GetError to achieve the same without having to carry around the
SDL_status all the time.

  • Daniel Vogel, Programmer, Epic Games Inc.

“Sam Lantinga” wrote in message
news:E153qhs-0002iz-00 at roboto.devolution.com

I’m looking for general feedback here from experienced developers.
As always, please do not turn this into a flame war, or I will stop
soliciting feedback.

Thanks!

Here are some proposed conventions for the SDL 1.3 -> 2.0 rewrite:

API conventions:

SDL functions return a boolean value or a pointer value

I thought ‘bool’ wasn’t available in pure C? If you mean an ‘int’ treated
as ‘bool’, fine, except where more information needs to be returned. But
see below.

SDL functions are prefixed with “SDL2_” … “SDL_” ?

I don’t like this, for these reasons:

  • I expect that at least some symbols from version 1.3 won’t need to
    be replaced. ‘SDLK_F1’ for example. It would be highly inconsistent
    to change mix ‘SDL_’ names with ‘SDL2_’ names, and it would be
    silly to rename things which aren’t even changed.
  • It sets an unfortunate precedent. What if version 3.0 completely
    changes the audio system, but leaves the video system intact? Why
    should a program that only uses the video system need to be changed?
    Or would version 3.0 keep the ‘SDL2_’ prefix?
  • I don’t like typing an extra character. :slight_smile:

I’m assuming here that 2.0 will essentially be a total rewrite of the
interface. That in itself might be a bad thing. Even if major interface
changes are necessary, I would favor an incremental approach over starting
over from scratch.

SDL functions take a status pointer as the first argument
This status pointer can be 0, but no error information will be saved.

I don’t really like this, but I can’t think of any significant technical
reason. This is slightly less efficient than returning the status because
an extra value has to be pushed onto the call stack. I also imagine that
checking for a null pointer, writing a value to a memory address, and
returning a ‘bool’ is quite a bit less efficient than just returning the
error code.

SDL_status status;
if (SDL_function(&status)) { // Which is failure: ‘true’ or ‘false’?
handle_error(status);
}

vs.

SDL_status status;
if ((status = SDL_function())) {
handle_error(status);
}

I suppose if a ‘SDL_status’ is a large object, the former might be more
efficient.–
Rainer Deyke (root at rainerdeyke.com)
Shareware computer games - http://rainerdeyke.com
"In ihren Reihen zu stehen heisst unter Feinden zu kaempfen" - Abigor

“Ryan C. Gordon” wrote in message
news:Pine.LNX.4.21.0105262351380.12693-100000 at gemini.verizon.net

Without starting the holy war ( :slight_smile: ), I’d personally beg for not using
tab characters at all, and just spaces (at indentions of four, if you
prefer).

I second that.–
Rainer Deyke (root at rainerdeyke.com)
Shareware computer games - http://rainerdeyke.com
"In ihren Reihen zu stehen heisst unter Feinden zu kaempfen" - Abigor

Could there be a SDL 1.2.0 to SDL2 wrapper ???
It would be nice to get things compiled without any changes.

Greetings
PeZ

At 07:55 PM 5/26/01 -0700, you wrote:

Here are some proposed conventions for the SDL 1.3 -> 2.0 rewrite:

API conventions:

SDL functions return a boolean value or a pointer value
SDL functions are prefixed with “SDL2_” … “SDL_” ?
SDL functions take a status pointer as the first argument
This status pointer can be 0, but no error information will be saved.

What do people think? Good? Bad? Ugly?

The coding conventions I acknowledge for the reasons stated, and the API
conventions I acknowledge as workable. However, is there an acceptable way
of making SDL_GetError() thread safe instead of adding the extra status
parameter to all applicable functions? (I presume thread safety is the
major reason for the status parameter addition.)

SDL functions take a status pointer as the first argument
This status pointer can be 0, but no error information will be
saved.
You could introduce the concept of a context so you could have
multiple SDL
contexts per application and have something like SDL_MakeCurrent and
SDL_GetError to achieve the same without having to carry around the
SDL_status all the time.

Hey, that sounds even better than what I suggested! I like this!–

Olivier A. Dagenais - Software Architect and Developer

I’m looking for general feedback here from experienced developers.
As always, please do not turn this into a flame war, or I will stop
soliciting feedback.

API conventions:

SDL functions return a boolean value or a pointer value

While I personally think this is great… I thought that the bool type was
part of ANSI C++ and is not a required type of ANSI C… (anyone feel free to
correct me if I’m wrong). I know that most C compilers allow for its use
(perhaps even all?), and that some compilers even treat bool in C cases as
standard zero/nonzero conditional cases… so for most (perhaps all?) this
wouldn’t be a problem…

But, if this is the case (again, feel free to correct me if I am wrong), then
this wouldn’t be “true” ANSI C and might not be completely portable.On Sat, 26 May 2001, you wrote:


Sam “Criswell” Hart <@Sam_Hart> AIM, Yahoo!:
Homepage: < http://www.geekcomix.com/snh/ >
PGP Info: < http://www.geekcomix.com/snh/contact/ >
Advogato: < http://advogato.org/person/criswell/ >

I’m sure there will be when SDL 1.3 is finally out (albeit, still being
developed)… I’d even wager that Sam Lantinga won’t have to even consider
making a wrapper…

I predict that within a few weeks of the first 1.3 dev release, we’ll see a
dozen or so wrappers from other developers just getting their app to compile
right ;-)On Sun, 27 May 2001, you wrote:

Could there be a SDL 1.2.0 to SDL2 wrapper ???
It would be nice to get things compiled without any changes.


Sam “Criswell” Hart <@Sam_Hart> AIM, Yahoo!:
Homepage: < http://www.geekcomix.com/snh/ >
PGP Info: < http://www.geekcomix.com/snh/contact/ >
Advogato: < http://advogato.org/person/criswell/ >

I’m looking for general feedback here from experienced developers.
As always, please do not turn this into a flame war, or I will stop
soliciting feedback.

Awww.
puts away the propane torch

Here are some proposed conventions for the SDL 1.3 -> 2.0 rewrite:
API conventions:
SDL functions return a boolean value or a pointer value
SDL functions are prefixed with “SDL2_” … “SDL_” ?

I’ll quote an IRC session from a few minutes ago:

So, show of hands, who is in favor of prefixing all SDL 2.0 commands
with SDL2_ (instead of SDL_)?

  • Xark keeps his hands firmly at his side…
  • overcode does not raise his hand
  • johns sits on his hands
  • morphriz eats his hands
  • parasite cuts off his hands
  • tesmako attempts to bite his hands off

Looks like there’s a bit of resistance to that proposal :slight_smile:

My personal sentiment is that we should not be overly concerned about
backwards compatibility. SDL 1.x will continue to be available; shouldn’t 1.x
apps be compiled with 1.x if at all possible? You’re well aware of the
troubles caused by different glibc versions. Although SDL is more tightly
controlled than glibc, SDL 2.0 is going to be a big step forward, and I can’t
help but imagine that there will be some compatibility issues, even if the
old function names remain prefixed with SDL and the new ones become SDL2.

Wouldn’t it be better to reimplement SDL, make its design perfect, and let
application authors choose whether to keep using 1.x or take the plunge and
upgrade to 2.0? Remember, reluctance to break backwards compatibility is the
reason we have Pentium IV’s running Windows ME today. (If I’m not mistaken,
that’s an uninterrupted line of progression from 8088’s running DOS 2.0…
and it really shows.)

My recommendation is to change the soname to libSDL2, continue using the SDL
prefix, and try not to make any API changes that would be TOO hard to port
from 1.x to 2.0. The open source community is resilient enough to deal with
minor changes, and regardless of what happens, it’s not going to be as much
of a mess as Qt 1.44 -> 2.0. Oh, and sdl-config should probably become
sdl2-config so apps don’t get linked with the wrong library.

BTW, I’ve been thinking about your C++ comments from IRC a few weeks ago, and
I’m starting to like the idea. I think that could result in a very clean
design. A long-standing bad taste for C++ was clouding my judgement, but I’ve
seen the light. :slight_smile:

SDL functions take a status pointer as the first argument
This status pointer can be 0, but no error information will be saved.

Good idea. I assume the performance hit of another argument to every SDL
function would not be noticeable. If you’re calling an API function in an
inner loop, you’ve got issues. :slight_smile:

Each function prototype will include a documentation section which
contains return value, parameters, and non-driver-specific error
conditions. It will also contain a brief note on thread-safety.
The documentation section is set off by /** so documentation tools
can parse it easily.

Excellent!

-JohnOn Saturday 26 May 2001 19:55, you wrote:


Underfull \account (badness 10000) has occurred while \spend is active
John R. Hall - Student, Georgia Tech - Contractor, Loki Software

SDL functions return a boolean value or a pointer value

While I personally think this is great… I thought that the bool type was
part of ANSI C++ and is not a required type of ANSI C… (anyone feel free to
correct me if I’m wrong). I know that most C compilers allow for its use
(perhaps even all?), and that some compilers even treat bool in C cases as
standard zero/nonzero conditional cases… so for most (perhaps all?) this
wouldn’t be a problem…

But, if this is the case (again, feel free to correct me if I am wrong), then
this wouldn’t be “true” ANSI C and might not be completely portable.

Just to clarify, my intention was 1 or 0, rather than an actual boolean type.

See ya,
-Sam Lantinga, Lead Programmer, Loki Software, Inc.

Here’s my 2 cents…

Here are some proposed conventions for the SDL 1.3 -> 2.0 rewrite:

API conventions:

SDL functions return a boolean value or a pointer value

I see where you’re going, and I like it. I’m not sure if you’re just
interested in feedback on your proposal or if you’re soliciting
submissions; if it’s the former than feel free to skip this :).

A different approach, that’s worked well (in practice) for me in the past
is to make every (or at least most) functions return a status, a long,
that represents various information about the function call. It can
contain any necessary information, that is accessable via macros; similar
to HRESULTS. Here’s an example off the top of my head.±----------------------+
bit(s) + 31 | 30 - 16 | 15 - 0 |
±----------------------+
meaning + S | L | C |
±----------------------+

S = success/fail bit. Basically. This would represent whether or not
the error is a fatal one or not.

L = the interface/lib that the error belongs to (i.e. video, audio,
etc…). 15 bits makes for A LOT of possibilities, so you could
specify a range that’s SDL only, and leave the rest open for
application specific stuff (e.g. you could make bit 30 say
whether or not it’s SDL or APP specific, and make 29-17 the
interface id itself). And inside the SDL range you could specify
another range (via a few more bits) to separate generic errors
(e.g. Can’t create window) from implementation specific errors
(e.g. Can’t init DirectX). Also, you could have a few hardcoded
interfaces, like one called errno. That’d allow you to wrap
errno values inside one of these.

C = the code itself.

And then have macros to build 'em and break 'em apart.
Something like
typedef long SDL_RESULT;
#define SDL_STATUS_CREATE(s,l,c) /* exciting shift ops here /
#define SDL_STATUS_CREATEI(s,lib,imp,c)
/
crate an implementation specific code /
#define SDL_STATUS_SUCCEEDED(result) /
bit 31 = 0 ? /
#define SDL_STATUS_LIB(result) /
result & bits 30-16, or whatever /
#define SDL_STATUS_CODE(result) /
result & bits 15-0 /
/
define status values /
#define SDL_SUCCESS 0
#define SDL_FAIL 1
/
define interfaces/libraries /
#define SDL_LNULL 0 //anything generic that’s not handled by errno
#define SDL_LERRNO 1
#define SDL_LVIDEO 2
#define SDL_LAUDIO 3
etc…
/
define implementations /
#define SDL_INULL 0 //non implementation specific errors
#define SDL_IWIN32 1
#define SDL_IQUICKDRAW 2
etc…
/
define implementation independant codes /
#define SDL_CCREATWIN 1
etc…
/
define implementation dependant codes /
#define SDL_CINITDX 1
etc…
/
define some errors */
#define SDL_EOK SDL_CREATE(SDL_SUCCESS, SDL_LNULL, 0)
#define SDL_ENOMEM SDL_CREATE(SDL_FAIL, SDL_LERRNO, ENOMEM)
#define SDL_ECREATEWIN SDL_CREATE(SDL_FAIL, SDL_LVIDEO,
SDL_CCREATWIN)
.
.
.
SDL_RESULT SDL_Init(…) {
SDL_RESULT result = SDL_EOK;
if (malloc failed)
return SDL_ENOMEM;
if (could not create window)
return SDL_ECREATWIN;
if (could not init direct x under win32)
return SDL_STATUS_CREATEI(
SDL_FAIL, SDL_IVIDEO, SDL_IWIN32, SDL_CINITDX);
return result;
}

/*

  • Much like strerror from errno.h.
  • Note that before I said ‘most’ functions return a status value.
  • This is a good example where it doesn’t really make sense.
    /
    const char * SDL_StrError(SDL_RESULT result) {
    /
    bigass array lookup/case statement to evaluate result
    or return the empty string if there’s no error
    */
    }

That thing I like about this is that its really just errno on crack. It’s
simple, thread safe, and it should be able to evolve well. The thing I
hate about it is that because every function returns a status, you
can’t use any functions as parameters to other functions. One could
perhaps mix this with a scheme like errno, where you have a global
variable instead of returning a status value for everything, but then you
get into threading issues. I wound up just biting the bullet and living
with the fact that you can’t return “real” (e.g. pointers) from
functions, but your milage may vary.

SDL functions are prefixed with “SDL2_” … “SDL_” ?

The only reason I can see this as necessary is if you plan on allowing the
user to use both SDL 1.x and SDL 2.x in the same app (and thus link to
both libs and thus have to prevent linker collisions). Is that the idea?
Otherwise my question would be “why?”

SDL functions take a status pointer as the first argument
This status pointer can be 0, but no error information will be saved.

In the scenerio I described above, the first parameter whould instead be a
pointer to a structure to be modified, if the function was to do that.
Here’s an example based on the current api.

SDL_RESULT SDL_LoadBMP(SDL_Surface** surface, const char *file);
void SDL_FreeSurface(SDL_Surface *surface);

void myfunc() {
SDL_Surface* surface = NULL;
SDL_RESULT result;

result = SDL_LoadBMP(&surface, “myfile.bmp”);
if (SDL_SUCCEEDED(result)) {
SDL_FreeSurface(surface);
} else {
fprintf(stderr, “could not load myfile.bmp: %s\n”,
SDL_StrError(result));
}
}

Anyway, that’s it. Sorry this went on so long; I tried to be as brief as
possible :). There are of course a ton of varients on this theme, this
is just one of them.

Dave

David MacCormack
@David_MacCormack

A different approach, that’s worked well (in practice) for me in the
past
is to make every (or at least most) functions return a status, a
long,
that represents various information about the function call. It can
contain any necessary information, that is accessable via macros;
similar
to HRESULTS.

I refrained from suggesting something like this, in case it was too
"Microsoft-ish" (and hence would lead to confusion as to real
HRESULTs, for example), but I think I like this better than passing a
struct.

/* define status values /
#define SDL_SUCCESS 0
#define SDL_FAIL 1
/
define interfaces/libraries */
#define SDL_LNULL 0 //anything generic that’s not handled by
errno
#define SDL_LERRNO 1

The only thing that bugs me about #defining constants is that
"intellisense" (or even “auto-complete”) can’t help you, whereas with
an enum you have scope and a stronger definition of what can and can’t
be used. Is “enum” a non-ANSI C thing?

The thing I hate about it is that because every function returns
a status, you can’t use any functions as parameters to other
functions.

That was also my reaction when I first saw ATL code, but the argument
was made that it’s a lot easier to debug this way and I couldn’t agree
more.–

Olivier A. Dagenais - Software Architect and Developer

“Olivier Dagenais” <olivier.dagenais at canada.com> wrote in message
news:9esdgk$20e$1 at ftp.lokigames.com

The only thing that bugs me about #defining constants is that
"intellisense" (or even “auto-complete”) can’t help you, whereas with
an enum you have scope and a stronger definition of what can and can’t
be used. Is “enum” a non-ANSI C thing?

Enums are superior for another reason: they respect namespaces. This makes
name collisions less likely. Example:

enum { A = 1 };
void f(void)
{
int A = 5; /* I’m pretty sure this is legal. */
}

For this reason I never use ‘#define’ where an ‘enum’ will do.–
Rainer Deyke (root at rainerdeyke.com)
Shareware computer games - http://rainerdeyke.com
"In ihren Reihen zu stehen heisst unter Feinden zu kaempfen" - Abigor

I refrained from suggesting something like this, in case it was too
"Microsoft-ish" (and hence would lead to confusion as to real
HRESULTs, for example), but I think I like this better than passing a
struct.

True, Olivier, it is “Microsoft-ish” :slight_smile: and HRESULTs are
definately what led me to try this out in my own applications.
HRESULTs are a solution to a specific question (how to implement error
handling in COM), and we’re talking about error handling in SDL.
I see no reason to conform to HRESULTs, but I have found it useful to use
the same tricks (bitmasks & macros); that’s why I made the suggestion.

The only thing that bugs me about #defining constants is that
"intellisense" (or even “auto-complete”) can’t help you, whereas with
an enum you have scope and a stronger definition of what can and can’t
be used. Is “enum” a non-ANSI C thing?

That’s very true (about auto-complete). enum is ANSI C (it’s even in K&R I
think). Because these are in reality just longs, there’s no reason why
you couldn’t use an enum.

typedef enum enum_SDL_RESULT {
SDL_ESUCCESS = 0,
.
.
.
SDL_EFAIL = 0x80000000
} SDL_RESULT;

You could still have the same macros to create/disect them/etc… too;
again, they’re still just ints. The only difference is, they’d have to
be specified all in 1 place (inside the enum) – though I don’t know if
that’s a benefit or burden – and for sanity’s sake, in the correct order.

I suppose there is the problem of architecture. An enum is an int (a
word) which would be at least 32-bits on most architectures that SDL
supports (maybe all???). But on those that have smaller word sizes, that
could pose a problem. However, one could probably get around it via some
clever #ifdefs…something like

#if /* int is 32-bits */

define SDL_BEGIN_RESULT_DECL typedef enum enum_SDL_RESULT {

define SDL_MAKE_RESULT_DECL(name,value) name = value,

define SDL_LAST_RESULT_DECL(name,value) name = value

define SDL_END_RESULT_DECL } SDL_RESULT;

#else

define SDL_BEGIN_RESULT_DECL

define SDL_MAKE_RESULT_DECL(name, value) const long name = value;

define SDL_LAST_RESULT_DECL(name, value) const long name = value;

define SDL_END_RESULT_DECL

#endif

SDL_BEGIN_RESULT_DECL
SDL_MAKE_RESULT_DECL(SDL_ESUCCESS, 0)
.
.
.
SDL_LAST_RESULT_DECL(SDL_ESOMETHING, 0xFFFFFFFF)
SDL_END_RESULT_DECL

That’s just a guess; there’s probably a better way.

DaveOn Sun, 27 May 2001, Olivier Dagenais wrote:

David MacCormack
@David_MacCormack

“Olivier Dagenais” <olivier.dagenais at canada.com> wrote in message
news:9esdgk$20e$1 at ftp.lokigames.com

The only thing that bugs me about #defining constants is that
"intellisense" (or even “auto-complete”) can’t help you, whereas with
an enum you have scope and a stronger definition of what can and can’t
be used. Is “enum” a non-ANSI C thing?

Enums are superior for another reason: they respect namespaces. This makes
name collisions less likely. Example:

enum { A = 1 };
void f(void)
{
int A = 5; /* I’m pretty sure this is legal. */
}

For this reason I never use ‘#define’ where an ‘enum’ will do.

On one level, a agree with you…it’s a very good point. But on the
other hand, we’re talking about something like #define SDL_ENOMEM.
I’d say it’s fairly unlikely that anyone will really want to create
variables with an “SDL_” prefix, so in practice it’s pretty safe (in my
experience anyway ;).

DaveOn Sun, 27 May 2001, Rainer Deyke wrote:

David MacCormack
@David_MacCormack