Thread overview | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
August 23, 2014 'idiomatic' porting of c and or c++ code that does NULL checking | ||||
---|---|---|---|---|
| ||||
I am learning SDL by following the lazyfoo SDL2 tuorials, I am alos new to D so I have a question: I the lazyfoo tutorials there are many functions that have a bool success whiich gets set at various places when something goes wrong to be returned afterwards. http://lazyfoo.net/tutorials/SDL/02_getting_an_image_on_the_screen/index.php for example: [code] bool init() { //Initialization flag bool success = true; //Initialize SDL if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) { printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() ); success = false; } else { //Create window gWindow = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN ); if( gWindow == NULL ) { printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() ); success = false; } else { //Get window surface gScreenSurface = SDL_GetWindowSurface( gWindow ); } } return success; } [/code] in my D code I just change the NULL into null and the printf to a fitting writeln. But I am wondering if D offers me much cleaner ways of writing this, I am guessing the scope() but what would be the best/D way of writing this function? How would you write it? |
August 23, 2014 Re: 'idiomatic' porting of c and or c++ code that does NULL checking | ||||
---|---|---|---|---|
| ||||
Posted in reply to nikki | Oops well writing the above post made me realise what to look for : http://dlang.org/errors.html ;) |
August 23, 2014 Re: 'idiomatic' porting of c and or c++ code that does NULL checking | ||||
---|---|---|---|---|
| ||||
Posted in reply to nikki Attachments: | On Sat, 23 Aug 2014 10:19:58 +0000 nikki via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote: don't use '==' to check for nulls. the right way is: if (foo is null) {} if (bar !is null) {} '==' transforms to opEquals call (see 'operator overloading') and 'is' not. as for 'best practice' question -- it depends of many things. ;-) |
August 23, 2014 Re: 'idiomatic' porting of c and or c++ code that does NULL checking | ||||
---|---|---|---|---|
| ||||
Posted in reply to ketmar | On Saturday, 23 August 2014 at 10:29:04 UTC, ketmar via Digitalmars-d-learn wrote:
> On Sat, 23 Aug 2014 10:19:58 +0000
> nikki via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote:
>
> don't use '==' to check for nulls. the right way is:
>
> if (foo is null) {}
> if (bar !is null) {}
>
> '==' transforms to opEquals call (see 'operator overloading') and 'is'
> not.
>
> as for 'best practice' question -- it depends of many things. ;-)
A good to know! thanks.
I'd still be interrested to see the idiomatic D version of that function, what would that depend on ?
|
August 23, 2014 Re: 'idiomatic' porting of c and or c++ code that does NULL checking | ||||
---|---|---|---|---|
| ||||
Posted in reply to nikki | nikki: > How would you write it? I don't know how much idiomatic this is, but you can start cleaning up the code: - Renaming the function with something more clear; - using a D enumeration for the various constants. - I have used a "." before the module-level variables to denote better they are not local; - I have used an alias and stderror. - All the code below is untested. bool initializeSDL() out { assert(.gWindow != null); assert(.gScreenSurface != null); } body { alias success = bool; if (SDL_Init(SDL.init_video) < 0) { stderr.writeln("SDL could not initialize! SDL_Error: ", SDL_GetError); return success(false); } else { .gWindow = SDL_CreateWindow("SDL Tutorial", SDL.qindowpos_undefined, SDL.windowpos_undefined, screen_width, screen_height, SDL.window_shown); if (.gWindow == null) { stderr.writeln("Window could not be created! SDL_Error: ", SDL_GetError); return success(false); } else { .gScreenSurface = SDL_GetWindowSurface(.gWindow); } } return success(true); } In D error messages are often given by throwing errors, so this looks a little more idiomatic: bool initializeSDL() nothrow out { assert(.gWindow != null); assert(.gScreenSurface != null); } body { if (SDL_Init(SDL.init_video) < 0) { throw new text("SDL could not initialize: ", SDL_GetError).SDL_Error; } else { .gWindow = SDL_CreateWindow("SDL Tutorial", SDL.qindowpos_undefined, SDL.windowpos_undefined, screen_width, screen_height, SDL.window_shown); if (.gWindow == null) { throw new text("Window could not be created: ", SDL_GetError).SDL_Error; } else { gScreenSurface = SDL_GetWindowSurface(gWindow); } } } If you can add some more function attributes, like @safe. Bye, bearophile |
August 23, 2014 Re: 'idiomatic' porting of c and or c++ code that does NULL checking | ||||
---|---|---|---|---|
| ||||
Posted in reply to ketmar | ketmar: > don't use '==' to check for nulls. the right way is: > > if (foo is null) {} > if (bar !is null) {} > > '==' transforms to opEquals call (see 'operator overloading') and 'is' not. I use "is" and "!is" for class references and == != for pointers. But now I think you are right, and in D it's better to always use is and !is for both, to avoid present and future bugs (like when a pointer gets replaced by a class reference by successive changes in the code). So the code I've written becomes: bool initializeSDL() out { assert(.gWindow !is null); assert(.gScreenSurface !is null); } body { alias success = bool; if (SDL_Init(SDL.init_video) < 0) { stderr.writeln("SDL could not initialize! SDL_Error: ", SDL_GetError); return success(false); } else { .gWindow = SDL_CreateWindow("SDL Tutorial", SDL.qindowpos_undefined, SDL.windowpos_undefined, .screen_width, .screen_height, SDL.window_shown); if (.gWindow is null) { stderr.writeln("Window could not be created! SDL_Error: ", SDL_GetError); return success(false); } else { .gScreenSurface = SDL_GetWindowSurface(.gWindow); } } return success(true); } bool initializeSDL() nothrow out { assert(.gWindow !is null); assert(.gScreenSurface !is null); } body { if (SDL_Init(SDL.init_video) < 0) { throw new text("SDL could not initialize: ", SDL_GetError).SDL_Error; } else { .gWindow = SDL_CreateWindow("SDL Tutorial", SDL.qindowpos_undefined, SDL.windowpos_undefined, .screen_width, .screen_height, SDL.window_shown); if (.gWindow is null) { throw new text("Window could not be created: ", SDL_GetError).SDL_Error; } else { gScreenSurface = SDL_GetWindowSurface(gWindow); } } } Bye, bearophile |
August 23, 2014 Re: 'idiomatic' porting of c and or c++ code that does NULL checking | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile Attachments: | On Sat, 23 Aug 2014 10:53:03 +0000 bearophile via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote: > I use "is" and "!is" for class references and == != for pointers. But now I think you are right, and in D it's better to always use is and !is for both, to avoid present and future bugs (like when a pointer gets replaced by a class reference by successive changes in the code). and "foo is null" is nice to read. ;-) |
August 23, 2014 Re: 'idiomatic' porting of c and or c++ code that does NULL checking | ||||
---|---|---|---|---|
| ||||
Posted in reply to nikki | On Saturday, 23 August 2014 at 10:19:59 UTC, nikki wrote: > I am learning SDL by following the lazyfoo SDL2 tuorials, I am alos new to D so I have a question: > > I the lazyfoo tutorials there are many functions that have a bool success whiich gets set at various places when something goes wrong to be returned afterwards. > > http://lazyfoo.net/tutorials/SDL/02_getting_an_image_on_the_screen/index.php > for example: > [code] > > bool init() > { > //Initialization flag > bool success = true; > > //Initialize SDL > if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) > { > printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() ); > success = false; > } > else > { > //Create window > gWindow = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN ); > if( gWindow == NULL ) > { > printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() ); > success = false; > } > else > { > //Get window surface > gScreenSurface = SDL_GetWindowSurface( gWindow ); > } > } > > return success; > } > > > [/code] > > > in my D code I just change the NULL into null and the printf to a fitting writeln. > But I am wondering if D offers me much cleaner ways of writing this, I am guessing the scope() but what would be the best/D way of writing this function? > > How would you write it? How about this? ---- import std.exception; // enforce() is declared in std.exception void init() { // enforce() throws an exception if condition is false enforce(SDL_Init( SDL_INIT_VIDEO ) >= 0, "SDL could not initialize!"); // enforce() throws if SDL_CreateWindow returns null gWindow = SDL_CreateWindow(/* ... */).enforce("Window could not be created!"); // ditto gScreenSurface = SDL_GetWindowSurface(gWindow).enforce("Surface could not be created!"); } ---- |
August 23, 2014 Re: 'idiomatic' porting of c and or c++ code that does NULL checking | ||||
---|---|---|---|---|
| ||||
Posted in reply to nikki | On Saturday, 23 August 2014 at 10:33:02 UTC, nikki wrote: > A good to know! thanks. > I'd still be interrested to see the idiomatic D version of that function, what would that depend on ? Honestly, I wouldn't change it much. If it didn't throw exceptions before, then it probably would have trouble handling them now. What I *would* do is use multiple returns though. This style of if/else invariably leads to the dreaded "diagonal line of death" (http://geekandpoke.typepad.com/geekandpoke/2009/12/geek-for-dummies-chapter-2.html) Once you've done that, any resource you'd have otherwise needed to Un-conditionally release, I'd do with a scope. bool init() { //Initialize SDL if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) { printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() ); return false; } //Create window gWindow = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN ); if( gWindow == NULL ) { printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() ); return false; } //Get window surface gScreenSurface = SDL_GetWindowSurface( gWindow ); return true; } Now, once you've adopted this kind of style, migrating to exceptions (should you so wish to do so) should much easier. |
August 23, 2014 Re: 'idiomatic' porting of c and or c++ code that does NULL checking | ||||
---|---|---|---|---|
| ||||
Posted in reply to ketmar | On Saturday, 23 August 2014 at 11:07:23 UTC, ketmar via Digitalmars-d-learn wrote:
> and "foo is null" is nice to read. ;-)
Meh, looks like a guest from pascal or basic.
|
Copyright © 1999-2021 by the D Language Foundation