Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - Jabberwocky

Pages: 1 2 [3] 4 5 ... 11
General / Re: Yet another RAII discussion
« on: February 12, 2016, 07:05:05 am »
It seemed to me that you were picking only the bits you like from that SO thread, in order to support your argument:

You mean like you just did when you only quoted the single line on unique_ptr?  And chose to delete the parts specifically discussing the overhead of other types of smart pointers?

implying "smart pointers have extra overhead", which is wrong. Without further relativation this statement is misleading.

It is not wrong.  Quit saying that.  Again, you are the one who is "picking only the bits you like" from the SO article.

The article lists the overhead associated with various different smart pointers.
That list does not say "smart pointers have no overhead".
That list does say "these types of smart pointers have this kind of overhead, which in some cases is zero.

It is fine for you to point out unique_ptr has no overhead. 

It is not fine for you to keep conveniently omitting the costs associated with shared_ptr.

It is not fine for you to keep calling me wrong, when the article clearly and plainly states there is overhead with certain aspects of smart pointers.

If you want to discuss the responsible and limited use of shared_ptr, due to the overhead it incurs, cool.  That is an informative conversation, based on the facts.

Unfortunately I'm going to need to ignore the next couple pieces of your post that continually reiterates the argument that smart pointers have no overhead.  Again, arguing for the restricted use of unique_ptr only is a different thing.  We can do that.  But it is different.

Yes, and typically, you can design your code in a way so that one of these pointers owns the memory and the others are just referrers. If you know in advance who frees the memory, you don't need shared ownership.

Ok, now we're reaching somewhere useful.
What do you do in this scenario?
Do you use a unique_ptr as the "memory owner" pointer, and a raw pointer in the "non-memory owning" copies?

If so, I actually think that is a reasonable solution.  But I think a lot of RAII advocates would have a problem with this.

But I'd also like to point out that manual memory management is completely sufficient in my case.  For my manager class which owns the memory, a simple delete call in the destructor completely handles the problem.

Fallacy #1: "I am using new/delete because I need more control over my code."
According to this logic, you'd program in C, if not Assembly.

If someone wrote a program in C, it worked, and it didn't leak memory, I would be 100% ok with this.  If they further claimed C provided all the tools they needed to achieve it, I would be 100% ok with this.

You keep speaking in absolutes.  I think this is where we will ultimately reach a stand still in our debate.  I believe in very few absolutes when it comes to coding.  I take into consideration the strengths of the coder, the requirements of the task, and the characteristics of any existing code base.  I am wiling to accept different tailored solutions (e.g. RAII vs. no RAII) depending on these factors.

regarding link-time:

I see, but I would really be surprised if this a) could not be deactivated (VAX has a step filter feature, so it's a matter of tools), and b) this would have a measurable impact,

I appreciate your suggestions.  But with large programs in visual studio, there's only so much you can do.  It's not just in my own code bases I've encountered slow link times, but also at every job I've ever worked at working on large software.

and c) this impact would outperform the time you lose if you make only one mistake related to manual memory management. You're paying a very high price for this.

You have no idea how much time, or how many mistakes I make using manual memory management.  You can assume, if you like.  Perhaps based on your own bad experiences.  But you should not project these issues onto me.

Fallacy #5: "Unique pointers are overkill in this situation"

Fallacy #XI:  "A single programming technique must be applied to all problems"

Fallacy #3: "Memory management is only unsafe when you use it incorrectly/in an unsafe way"

Fallacy #VII:  Manual memory management cannot be done safely.  It can, and has across many years in millions of programs.

Just look at Font.cpp, it's a big mess with tons of different resources that all need to be deallocated in different ways, and failure to load one must account for all the others. A C++11 handle class with move semantics would simplify this code dramatically, while making it more robust at the same time.

I had a look at Font.cpp.  Based on a very quick brows of the code:
There are 3 variables that use new/delete:  m_refCount, m_stream, and a m_streamRec. 

There are 5 calls to new.
There are 6 calls to delete.
That hardly strikes me as an unmanageable "big mess".

Some of these are due to a hand-rolled pointer-based reference count.  I probably would have advocated for a different solution.  I would not have objected to smart_ptr in this situation. 

There appears to be other dynamic memory allocation via calls to FT_Get_Glyph and FT_Done_Glyph.  Based on my quick examination, this does not appear to be something smart pointers would help with, as you are restricted to the syntax provided by FreeType.

If you consider this an unmanageable problem without smart pointers, I would suggest we have different abilities to deal with manual memory management.

You have not been developing it. Because in the API, SFML doesn't use raw pointers that own memory. At least I don't recall an interface that expects you to allocate something with new, or gives you something that you must deallocate with delete.

Yes, SFML is written with good memory management.
I have found the code a pleasure to work with.

Fallacy #4: "Many people use smart pointers incorrectly"

Fallacy#XXIII:  Smart pointers are always used correctly.
Fallacy#XXIV:  Smart pointers will guarantee your programs (and libraries you employ) do not leak memory.

There may be a few situations where you need a more flexible/loose form of RAII, like shared ownership. And there are higher-level "leaks" like cyclic references or std::vector::reserve() that are out of RAII's scope.

So we are in agreement memory leaks may occur regardless of the use of RAII.
That was the primary point of my original post.

Programmer errors are not a good argument because bugs in the memory leak detector can occur as well, and even more so with manual memory management. And as many threads in this forum (maybe this one too?) show, it's possible to use leak detectors incorrectly, or interpret their results in a wrong way. So it only guarantees something as long as you use it correctly, and we're back to the circular logic.

Yes, memory leak detectors can be used incorrectly.
Yes, RAII can be used incorrectly.
Anything you use incorrectly can cause problems.

I provided a ton of rational arguments for RAII, I even skimmed through many places in the Internet to collect different views on the topic and write a detailed article about it. It's not a matter of taste or "art" (fallacy #6), but hard facts. And I did not call you foolish.

Pardon, you say ignorant, not foolish.

As noted above, I believe we are at an impasse.  We believe fundamentally different things about the art of coding.

I did want to respond though, to clarify my opinion.  And to refute your repeated assertions that I was incorrect.  If you want to keep posting that, there is nothing more I can do than what I have written above. 

I also responded to to demonstrate how unhelpful it is to post these absolute "fallacy" rules, when I can just as easily post opposing fallacies.  Discussing in terms of these false absolutes does nothing to further the conversation.

However, I am genuinely interested in your technique in dealing with "multiply pointed to" memory in RAII, without the use of shared pointers.  Should you decide to elaborate.  I appreciate that aspect of the discussion.

General / Re: Yet another RAII discussion
« on: February 11, 2016, 07:56:25 pm »
He's actually making a good point, and there's a ton of resources to be found on the Internet that back up his claim. In this forum alone this has been discussed so often that it almost seemed like people would agree.

So the rule is, you can discuss RAII if you are proposing it is a useful solution.

You cannot discuss RAII if you are critiquing its use as a solution - that's hijacking.
Is this correct?

Truthfully, that strikes me as a bias to shut down arguments you disagree with.

It was mainly a link to my article, hoping that people will read it and I don't have to re-iterate everything again. An in-depth reasoning can be found there.

I have read it.  It's a good article.  But it does not mean that there is not also good in-depth reasoning NOT to use RAII.  I think you are mistaken if you believe your article is programming gospel that should override any and all discussion on it.  The internet is equally filled with people who critique RAII and smart pointers as those who advocate for it.

I don't see any insults. I'm sorry if my post came across that way.

Thanks for saying sorry, I appreciate it.
There's a few things which were pretty inflammatory.  Here's one:

Maybe you should read the links you're posting. Smart pointers have no overhead, when used in a way semantically equivalent to manual memory management.

I obviously did read the article.  I wouldn't have posted it otherwise.  That's an extremely dismissive and insulting thing to say.  I would also argue you're incorrect.

Here's a quote from the top rated answer from that article.

std::unique_ptr has memory overhead only if you provide it with some non-trivial deleter.

std::shared_ptr always has memory overhead for reference counter, though it is very small.

std::unique_ptr has time overhead only during constructor (if it has to copy the provided deleter) and during destructor (to destroy the owned object).

std::shared_ptr has time overhead in constructor (to create the reference counter), in destructor (to decrement the reference counter and possibly destroy the object) and in assignment operator (to increment the reference counter).

Granted, he does say the performance hit is small.  But it is 100% incorrect to say they have no overhead.  So not only did I read the article, but it explicitly talks about the overhead of smart pointers.  Relevant to the discussion, wouldn't you say?

Now, your argument is that
Smart pointers have no overhead, when used in a way semantically equivalent to manual memory management.

But that is not the discussion we're having.  No one has suggested we're merely replacing regular pointers with unique_ptr.  The discussion is whether to use RAII vs. not using RAII.  RAII, in cases where you need multiple pointers to the same memory, advocates the use of shared_ptr (even if it does recommend using it sparingly).  So it is not a choice merely between raw and unique_ptr.  That's a false equivalency.

There are certainly places in my (non-RAII) code where I have multiple pointers to the same memory.  This is wise not to overuse, but it has its place.  I do not use shared_ptr.  I do not use reference counting, either.  Rather, I have a well structured and known lifetime of this "multiply pointed to" memory, which can safely guarantee the duplicate pointers will be safe to access where used in the code.

This is faster, with less overhead, than the corresponding RAII solution would be.  Personally, in situations like this, I also find being closer to the metal, using raw pointers rather than the added abstraction of smart pointers, allows me an easier mental model of what is actually happening. I consider this valuable.

Here's another quote from the 2nd highest rated answer:

You can expect some overhead in debug builds, since e.g. operator-> must be executed as a function call so that you can step into it (this is in turn due to general lack of support for marking classes and functions as non-debug).

In my particular case, debug performance is very important.  This is because my primary code cycle is:  code, compile debug, run debug.  This is mainly because my projects are big enough that release linking is slow, which has a significant impact on the code-compile-run turn around cycle.  And there is the added advantage of being able to step immediately into the code without a mangled stack.


Now, I'm not saying RAII is terrible.  I think there are scenarios where it is a useful tool.  Perhaps one is in large code bases maintained by multiple programmers of various skill level, where the extra layer of safety is necessary, or the programmers lack the skill, experience, or even the just perfected habits to manage their memory manually.

For me, RAII is like someone suggesting I wear a helmet to bed, in case a meteor crashes through my roof and kills me.  I'm just not worried about the problems that RAII helps solve.  I am happy with my existing solutions.  They work fine.

You argue against this in your article.  You call this ignorant.  Let me ask you this - SFML does not use smart pointers.  Is this ignorant?  How often is SFML affected by it's lack of smart pointers?  How about in a way that has not been trivially easy to fix?  I certainly have never had a problem with SFML's use of raw pointers.

And finally,
So, when you have the choice between a technique to fix a problem after it occured, and one that prevents it from even appearing in the first place, you decide for the former. Sounds reasonable.

That's both sarcastic and snippy by the way.  ;)
But it doesn't attempt to address the point I made.  Which is that RAII does not guarantee you've fixed the problem.  As I said originally, yes, it helps prevent it.  But it does not guarantee there are no programmer errors, either in your code base, or in those of the libraries you employ.  The only guarantee is a memory leak detector.

If you'd like to call into question my reasonableness, please do so by addressing the reasoning I presented.

A final word - I get that you like RAII.  I get that it works for you.  That's cool.  But, as they say, programming is as much an art as a science.  To claim that people are foolish who chose to employ their art differently than you, that their reasoning is debunked, is a narrow minded view of the art of writing code. 

You may disagree with my reasoning.  And I with yours.  That's fine.  But I do not disrespect you for your decision.

General / Re: Yet another RAII discussion
« on: February 11, 2016, 01:34:55 pm »
Oh nice, another discussion about RAII. Fortunately we haven't had enough of them in the past. If there is really a need to discuss this yet another time, start another thread, and don't hijack the thread about leaks in SFML.

Incidentally, I didn't bring it up.  I only responded because, unprompted, eXpl0it3r critiqued the use of memory leak detectors by the thread author by suggesting RAII made them obsolete (which is fine, he's sharing an opinion).  So even though you quoted me, I'll assume your sarcastic reprimand was aimed at eXpl0it3r.

Although I am still a little confused.  You ask that we not hijack this thread to discuss RAII.  You follow that statement immediately with a discussion of RAII.  That in itself does not make a lot of sense. 

Normally, the point of doing such a thing would be to have a debate.  I guess I'll assume you're not interested in such a debate however, or that your rules of hijacking threads apply only to others and not yourself.

I'm ok with that, though.  Given that you filled your response with both sarcasm and insults, things a person doesn't do when seeking a positive and productive exchange of ideas, I wouldn't have been interested anyway.  I try to communicate in a positive manner and with an open mind, even and especially with people I disagree with.  If you approach things being condescending and closed minded, you neither end up learning anything new yourself, nor convincing others of your opinion.  So the "debate" is a waste of everyone's time.

General / Re: Yet another RAII discussion
« on: February 10, 2016, 04:16:42 pm »

SFML projects / Re:creation - a top down action adventure about undeads
« on: February 10, 2016, 01:39:00 pm »
I won't comment on the lua scripting system, I've not much experience with it since I don't use one myself.  But the game looks to be coming along really nicely, Elias!  Agreed, setting some milestones for yourself (the demo) is a great idea.  Sometimes we programmers like to disappear down rabbit holes for a long time without such milestones.  ;)

SFML projects / Re: Cendric: An RPG Platformer
« on: February 10, 2016, 01:34:01 pm »
That physics stuff just screams out "use Box2D" to me.  But if it's for learning purposes, it makes sense to do it yourself.

Regardless, agree the platforms are cool and make for some interesting puzzle pieces!
Thanks for the update, Ironbell.

General / Yet another RAII discussion
« on: February 10, 2016, 01:21:43 pm »
To be honest if you stick to modern C++ with RAII memory leak tracking will become obsolete pretty quickly.

Alternatively, memory leak tracking solves the same problem as RAII does, but does not involve the extra overhead and ugly syntax of smart pointers. 

Except that memory leak tracking alone is sufficient to find any problems. 

RAII alone is not sufficient to prevent memory leaks (although it certainly helps), as it of course relies on there being no programming errors, in either your code or 3rd party library code.

So, if you're choosing between the two, memory leak tracking is a better choice.

Just another opinion.  :P

SFML projects / Re: Let There Be Light 2
« on: February 06, 2016, 03:36:33 pm »
There is a dedicated example in the repository.
I do have a separate RenderTexture for the normals.
The idea is that each time you draw something,you also draw the normals version of it to the normals texture:


That way, whatever your scene graph is, you'll get a full representation of your scene in normals.
I think this is flexible enough to adapt to each system.

Afterwards, when the light system renders its lights, it will use the full normals texture for each composite part.
And you get the usual LTBL light texture to add to your scene (but with normals matching your scene!).

Ahh, right, that totally makes sense.

I was thinking about it in the wrong way (storing the light direction in a texture, not the scene normals).  It kind of works like a 3D deferred rendering pipeline.


SFML projects / Re: Let There Be Light 2
« on: February 06, 2016, 11:38:39 am »
A small thing I'm doing is getting rid of std::shared_ptr<> in the interface, as the shared pointer is not stored internally in the library, I really don't get why there is this restriction. Doing so, I'm using offering a way to let LTBL manage the lights memory for the user, using some pre-allocated memory pool.

I got rid of the shared_pointers in the interface, too.

I added a way to have the light react to normals, but one can imagine more (specularity/depth maps). And I've been doing so just for point lights, it needs to be extended to directional lights.

This is an interesting one.  I've been considering doing the same thing.

Since LTBL just spits out a texture you overlay onto the scene, I'd be interested how you accomplished this.  Do you output a second texture of light direction, which can be used in a shader to combine with the normals?  The only problem there is that you couldn't combine these textures in the same way LTBL combines its light textures into a composite overlay texture.

I am not an expert in that domain, but I was wondering if I could compute some parts of the code in parallel.

Neither am I.  Although it does seem like the kind of code which could be run in parallel.

There's no doubt LTBL has a significant impact on performance.  Although I haven't measured whether that performance is primarily CPU or GPU (in which case running the code in parallel wouldn't matter). 

I'll soon launch a Greenlight trailer for the game I'm developing, hopefully LTBL will make it shine! :)

Awesome, and good luck!  Make sure you post a link here so we can upvote.

SFML projects / Re: Cendric: An RPG Platformer
« on: February 03, 2016, 08:35:16 pm »
Pretty impressive for a "learn c++" project.  :)
That water effect is particularly neat!

SFML projects / Re: Let There Be Light 2
« on: February 03, 2016, 11:47:46 am »
Cool stuff, Breush!
I'd be interested to hear about any ongoing work you do, and really appreciate you sharing.

SFML projects / Re: Rage - a coop dungeon crawler
« on: January 29, 2016, 03:52:31 am »
I love roguelikes! 
Nice to see things up and functional in Rage.

The background art is obviously pretty barren still, but I agree with getting the core mechanics up and running before dealing with the window dressing.

SFML projects / Re:creation - a top down action adventure about undeads
« on: December 17, 2015, 11:12:58 pm »
If an overload exists for the type of v, the compiler will automatically choose it. If it doesn't, the compiler will complain. The point is, the serialization code remains generic, it only has to call json::serialize and the compiler does the rest, as long as a compatible overload exists.

This is pretty close to how I've implemented XML serialization in my game.

You've given a lot of fantastic advice in this thread Laurent, and it's cool seeing the SFML devs so involved in these devlog threads.

Jabberwocky, dabbertorres, I'll think about it. There's just so many stuff I don't have to save to the save file, for example, component's default values which are stored in entity definition files. I only have to save stuff which is unique for entity: it's position, current state, HP, inventory, etc.
But, there's sometimes no need to save  HP or current position which most games don't do and they're fine. So, as for now, I'll be writing game saving/loading code by hand by thinking carefully about what I have to save and what I don't.

Absolutely.  You don't save the same data to a savegame file as you would to an entity definition file.  It should only be "dynamic state" stuff, like position and inventory, as you mention.

What I am saying is that in both cases (editing, saving) you need to serialize and deserialize data to a file.  And that it's useful to be able to open and read your savegame files (in a non-binary format).  So JSON may be an ideal format for both.

SFML projects / Re:creation - a top down action adventure about undeads
« on: December 17, 2015, 12:02:34 am »
No doubt, decent tools can make or break a game, especially content heavy games like an RPG or action adventure.  I've enjoyed watching you hammer out your approach with the editor, Elias.  And the JSON <-> C++ serialization.

One thought - you may also want to be thinking about saving and loading functionality while you're at it.  Like, the "save game" and "load game" buttons.  It's very much the same kind of serialization/deserialization type of problem.  I'm personally a big fan of having a human-readable save file format (like XML or JSON), as this can help immensely during development and debugging.  As opposed to a binary format.

So, maybe you can use the C++ <-> JSON serialization for saving and loading the game, just like you do in your editor for authoring animations and other game content.

Graphics / Re: Question for best performance
« on: December 16, 2015, 12:56:43 am »
I'm pretty sure you'd have to go back at least a decade to find an intel integrated card incapable of handling 1024x1024.

Pages: 1 2 [3] 4 5 ... 11