Posted by BitMaster
on 03 February 2015 - 02:29 AM
I have no clue why std::string and std::list even appear in the same sentence here. While I don't think the standard requires a particular kind of internal storage for an std::string, it needs to support std::string::c_str and storage as anything but a glorified std::vector would be inadvisable (although several std::string implementations do not require allocations for small strings).
That said, I'm really not sure where your enthusiasm for trying to optimize std::list is coming from, especially since it sounds you really want an std::deque in the first place. And while I used to believe (when I was much younger and inexperienced) std::list was a very useful data structure in the past I have found that in actual practical experience it's probably the least used of them all.
Personally, I'm a big fan of modularization. However, I would consider actual DLLs as the last alternative for that. Static libraries are almost always doing a much better job with less headache. If you have megabytes of shared code between executables used next to each other, then yes, DLLs might be something for you if it outweighs the problems (see below).
There is no problem using classes across DLL boundaries (extremely important detail: if you know exactly what you are doing). For a start, name mangling across different C++ compilers will in general not be the same. So using C++ code (that's not just about classes, it's about anything not marked as pure C) across different compilers (or even different versions of the same compiler) will not work correctly for the simple reason they cannot find the functions they expect to find. Just because one compiler put an 'int myFunc(char*)' into the DLL does not mean another compiler can even find it. If you build both the DLLs and the executables using it with the same compiler (and the same build settings), you are clear though.
That's one part of the problem. Another problem is that you need to take care about where something was allocated and where it is freed. If the DLL newed something it can hand out that pointer to another DLL or the executable where it can be used. You are not allowed to just free that pointer in another module though. This can be worked around if both modules use a runtime which explicitly allows that (like /MD for MSVC). This is the reason why libraries generally offer a CreateXXX/DestroyXXX pair of functions for XXX you can create. Take note that if the runtime is updated you might have to ensure both executables and DLLs are all rebuilt and deployed using the same version of the runtime. I'm not sure how frequent that is but it happened to me at least once for MSVC 2005 or 2008 and missing an executable or DLL in a deployment can lead to highly annoying and difficult to track down bugs.
As a side effect of the above paragraphs, unless you can make sure you are using the exact same compilers and the exact same build settings standard library containers (including, say, std::string) are usually out for the public DLL interface. I say 'build settings' because that's not just about the runtime library used. For example MSVC allows to configure (among other things) iterator debugging at compile time using defines. If these defines are not identical extremely bad stuff will happen.
In summary, I'd like to reiterate once again: if all you are after is a bit of organization and modularization, forget about DLLs. Static libraries do that job wonderfully without any of the problems. If you really, absolutely need DLL functionality treat carefully and expect problems while you learn the ropes.
That's a classic violation of the Rule of Three (or the newer C++11-counterparts) and it should probably only fulfill std::is_probably_broken.[/size]
Not always. The rule of three says if you have one, you probably should have all three. There are absolutely valid cases for having one-or-more, but not all.
For example, if all the members of your class leverage RAII, there's no need to explicit define a destructor, even if you needed to define a copy constructor or assignment operator (or delete one of the same) because one of the members was a reference or const.
I find it difficult to agree with this statement, probably because I have spent at least one day too much debugging code where the root cause turned out to be a Rule of Three violation after a lot of suffering. I would say in practically all cases where a contained RAII resource is present you do not need to specify any of the three (because the compiler will automatically generate them based on what is already defined or not defined for the RAII resource).
Also, if there is a RAII resource inside the class then it's not going to have a trivial destructor, then the class which contains it won't have that either and my statements were in the larger context of whether a std::is_trivially_destructable would have a real use. I maintain 'no' on that count.
With a bit of creativity I'm sure one could cobble together an actual use case for going against the Rule of Three. But I also believe those are so rare it should lead to more than normal reflection about if it's really okay.
I would disagree. If an object fulfills a theoretical std::is_trivially_destructable but not std::is_trivially_copyable it has non-trivial copy and/or move semantics without a non-trivial destructor. That's a classic violation of the Rule of Three (or the newer C++11-counterparts) and it should probably only fulfill std::is_probably_broken.
Out of curiosity, does anyone know if there is any chance the swap can be optimized to a move when the items don't have destructors? I guess that could be difficult unless the memory in the vector is actually shrunk.. Not that it should really matter, but for large POD types it seems unnecessary to exchange the memory instead of just copying.
C++11 introduced a POD testing template, so you could write:
I had a bit of déjà vu when I read that and after going back through your old threads I learned why. Back in 2012 you made a thread that's very similar: extremely low on facts but lots of strong opinions, tons of pathos and a good dosage of completely wrong. And the same religious prosecution reference. My personal advice would be to drop that religious prosecution stuff first. It just screams "nutcase". Unless you really actually believe it. In that case I would advise professional help.
I was pondering for a bit whether I should try to talk about whatever facts (or supposed facts) I could find in your posts but then decided against it. There is so much hyperbole and pathos in it, I really don't want to read it a second time in the hope of finding something to work with. Besides, I'm fairly certain the bug I was hunting is fixed now and I just won't have the time while I wait for my processing step to run through.
Offhand, I'd say to make sure you're linking in the correct order (i.e. graphics, window, then system). Make sure you're setting things either globally, or make sure you're linking and compiling in the same mode (debug or release).
That's a runtime error, not a linker error. Linking sequence won't have an effect under normal circumstances.
If you're trying to link statically, I'd recommend trying to get it up and running dynamically first, as static with sfml gets a little awkward as you need to link all the dependencies and include things with your project, amongst other things.
According to the screenshot he is already linking dynamically. Granted, it would be better if he described what exactly he was doing instead of posting a single screen shot and then letting people guess, but the problem appears to be a symbol not being found in one of SFML's DLLs.
Lastly, you may want to build sfml yourself, if you're doing absolutely everything else correctly. I don't mean to complicate things further, but it's possible there are minor things keeping it from working for you that aren't due to user error (newer/older version of codeblocks, your version of gcc, etc, etc).
Here I can agree with. The error looks weird but without further information my guess would be a name mangling issue. Especially with MinGW having the library precompiled for your exact flavor of the compiler is important (there are up to three different exception models for Windows and two big different runtimes you might be using). Additionally my personal advise would be to start learning C++ with one of the MSVC Express editions when you are working on Windows to begin with. It's far easier to get working, precompiled binaries for most common libraries for that compiler. Using MinGW will in most cases require you to compile the libraries you need yourself. That is not a bad thing at all, but when you are starting out that's not something I recommend dealing with as well as everything else.
i've tried the exact same steps but still got an error
Here is an important lesson to learn: saying "I get an error" makes it practically impossible for people to help you. The error contains a lot more detail than just its presence. The text that is part of the error might not mean anything to you yet but without it no one can really help you.
It should be noted that using an std::array<> would probably have caught the error earlier in this case since most implementations will assert in operator regarding the validity of the index (without sacrificing speed or space in non-debug builds).
Apart from that, writing beyond the array boundaries is always nasty to debug. If you have your code in some kind of version control system (a good advice in all cases), going back and checking when these errors stop appearing can give clues. Otherwise commenting out bits of code can give clues as well.
Edit: but the best course of action is avoiding situations like this entirely. As above, the std::array<> would have caught the problem, unlike the C style array. If you need a dynamic size, std::vector with the desired size passed to the constructor can work too. If you only access it via operator  it will assert on bad indices as well and not grow automatically.
The problem is most likely unrelated to std::vector. Maybe someone is writing beyond array boundaries somewhere (and thereby threshing the memory belong to the std::vector) or maybe you are working with a vector inside an object which has been deleted or went out of scope. The best approach (on MSVC) would be to switch to a Debug build and start it with the debugger. Ideally one of the several additional checks running there will trigger an assert closer to the point where crap actually happens.
First minor issue: You shouldn't start your variable names with an underscore. Variable names starting with underscores are reserved for the compiler.
That is incorrect like that. According to this post which reinforces my previous suspicion, his use of underscores is without issues. He is using a single underscore followed by a lower case letter which the standard allows him to. I'm not a fan of that notation but those are stylistic complains, not technical. I am however rather annoyed whenever I see (void) as a function parameter. The code is obviously C++, could never be C, so there is absolutely no point in putting that there.