Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 08 Aug 2000
Offline Last Active Today, 08:07 AM

#5265695 Vector mock to catch bad accesses

Posted by BitMaster on 10 December 2015 - 02:45 AM

Further, please refrain from insulting and otherwise disparaging anyone who does post such opinions.

I was pondering how to respond to this. But since this is not For Beginners and the core topic of the thread has been successfully solved I'm going with 'spinning off a tangent from the tangent'.

I'm going to assume that is directed at me and I would like to object to it. The statement I was referring to was extremely unhelpful. Especially in the context of the thread, but even in a thread where a discussion of the standard library was intended it failed on all relevant levels.
The core problem started with the choice of 'hate'. 'Hate' strongly implies a purely emotive reaction instead of a rational one which really has no place in a technical discussion. What else was I supposed to do? Just downvote him? I can respect the decision of the people who did by now but I considered it unhelpful.
So instead I decided to challenge the statement directly. While I admit what I said could be construed as a bit disparaging I also don't see how to avoid that. Sure, you can wrap up the statement into so many layers of cotton that it becomes less noticeable but then you also start losing important signal about what you are objecting to.
I can honestly say the only times I have encountered statements like "I hate std::vector" was people either (a) trolling or (b) having run into a problem with them because they were unaware of its semantics. People who are dealing in scenarios where using std::vector is legitimately a less optimal solution express themselves in completely different ways (and usually have the wisdom not to inject such a discussion into places where it is not warranted).

I realize that was not a formal reprimand but if it was, I would be appealing to another moderator now.

#5265693 std::thread arguments and copies

Posted by BitMaster on 10 December 2015 - 01:56 AM

I highly doubt it has something to do with the standard, MSVC has been rather bad at dealing with C++11/C++14. Their standard library just had so many holes and workarounds.

One of the core reasons I switched my hobby work over to non-MSVC compilers was to gain access to reasonably complete implementations of C++11 (and later C++14). In the process I noticed myself gaining a lot of skill points in related areas and I have also come to enjoy the experience. Even if MSVC 2015 should be a decent implementation of C++14 I would not consider switching back for the foreseeable future.

Edit: @jbb: I would be happy to discuss whatever you are objecting to but I see a commentless downvote in this scenario as extremely unhelpful.

#5265653 Vector mock to catch bad accesses

Posted by BitMaster on 09 December 2015 - 04:17 PM

"I hate std::vectors" was not a defining statement that they are terrible. I just don't like to use them. I am not discrediting their existence or ability to perform the job, I myself just have a personal dislike of them. Assuming someone's level of understanding is somewhat of an underhanded insult btw.

Then I suggest you either get into the habit of choosing more neutral language or explaining your point of view in more detail. With what you wrote there is really only the reader's choice between "tries to troll" or "does not know what he/she is doing".

#5265649 Vector mock to catch bad accesses

Posted by BitMaster on 09 December 2015 - 04:00 PM

some random crashes started to occur with very random error messages from the compiler.

Is your compiler actually crashing and giving you error messages? Or are you trying to say that your compiled program is crashing when you run it?

So, is there an alternative version of array/vector which actually throws and exception(or gives some message) when the index is outlimits?

In general you do not want throwing exceptions here since you never should access an invalid index in the first place. What you want is an assert (usually only enabled during debug builds but up to you). Of course with a decent compiler and a bit of debug info you should not even need that since you just run into a crash and then walk up the call stack until you see where your program tried to access an invalid index.

Would it be a better idea to actually inherit from vector/array and override the index operator?

Standard library containers are not intended to be inherited from. I have never seen a legitimate use for it either.

PD: The debugger won't help either in this case. The crashes are very random.

Of course the debugger helps even in those cases.

I hate std::vectors.

I love std::vector. There are legitimate reasons not to use it in specific circumstances but anyone 'hating' it probably does not understand it well enough and would run into the same or worse problems with something hand-rolled.

Edit: For example for gcc's typical standard library you can add define _GLIBCXX_DEBUG and get nice error messages like this:
    error: attempt to subscript container with out-of-bounds index 10, but 
    container only holds 10 elements.

Objects involved in the operation:
sequence "this" @ 0x0028fe44 {
  type = NSt7__debug6vectorIiSaIiEEE;
I believe MSVC automatically does a bounds check when you build the standard Debug configuration but I don't have it here to test at the moment and it's been a while since I was worried about that particular kind of error.

#5265601 std::thread arguments and copies

Posted by BitMaster on 09 December 2015 - 11:50 AM

MinGW 4.9.2 with -std=c++14
struct Test
		std::cerr << "constructed in " << std::this_thread::get_id() << "\n";
		std::cerr << "destroyed in " << std::this_thread::get_id() << "\n";
	void call()
		std::cerr << "called in " << std::this_thread::get_id() << "\n";

void testFunc(std::unique_ptr<Test> test)

int main(int argc, char* argv[])
	std::thread thread(testFunc, std::make_unique<Test>());

        // ...
Compiles fine and has the expected output:
constructed in 1
called in 2
destroyed in 2
The project I quickly injected it in relies on some C++14 stuff and I was too lazy to work around that but there was really nothing much in C++14 which would change semantics so fundamentally. Considering my past bad experiences with MSVC and standard (non-)compliance, I'm going to blame MSVC here unless someone can dig mitigating circumstances out of the standard.

#5265579 std::thread arguments and copies

Posted by BitMaster on 09 December 2015 - 08:08 AM

My reasoning was on similar lines of Hodgman, however since a sensible implementation should prefer moving over copying you should never have more than one reference counted anywhere and it should work. If it did not work like that, transferring a std::unique_ptr<> instead of std::shared_ptr<> would be impossible and although I cannot remember ever having done that I'm pretty sure it should be possible. That said, at least the documentation over on cppreference.com is not as clear as it could be and I'm unsure if it is guaranteed behavior. Maybe going to the actual standard would help but I'm currently in no mood to do that digging.

#5265438 Writing 'floats' to a file

Posted by BitMaster on 08 December 2015 - 08:52 AM

The general expectation of operator << and >> with std::stream classes is to have text in/output. I would strongly recommend against doing binary input/output for some types. It's counterintuitive when reading the code and it's far too easy to accidentally serialize types textually inside your normally binary representation.
If you want to keep using << and >> I would strongly recommend defining your own binary_stream type which does not share operators which the normal std::stream classes.

#5265257 Efficient Error Handling Methodology/Best Practices

Posted by BitMaster on 07 December 2015 - 07:59 AM

I've had this happen multiple times, where a customer managers to trigger an edge case that we had never encountered during testing. Customer experiences crash or other negative behaviour, we reproduce in house... well, of course it failed. See, it dereferences a null pointer. What idiot wrote this code without a null check? The same idiot that put an assert(x != nullptr) a few statements before.

I don't see how that is primary that programmer's fault or even deserves calling him/her an 'idiot'. As far as I can see there are three possible scenarios:
  • The contract specified passing null is not allowed. In this case there is no fault at all on the programmer. He did the best he could on his end and then whoever wrote the calling code messed up.
  • The contract specified passing null is allowed. In this case the programmer in question shoulders a bit of the blame in question but the majority should fall on whoever did not write a proper test case for important edge cases.
  • The contract is ambiguous and does not really specify anything. In this case I feel his/her pain and the best possible was done. Either the input cannot be null or if it can, at least the situation will be cleanly detected via assert during testing.
Personally I have made nothing but good experiences with asserts. Missing asserts have sometimes caused me to lose hours or days though, whenever something goes boom in a rather cryptic place while an assert a few levels up would have given an immediate hint what goes wrong. I am however working in an environment where everyone is clear what asserts are for and would never think of using them for 'handling' errors which could happen. If you cannot rely on that, banning asserts might be one way to go. Personally I would say that in such an environment working with C++ is a recipe for tears to begin with.

#5264608 MyClass myClass VS myClass = new MyClass()

Posted by BitMaster on 02 December 2015 - 12:40 PM

Never had much practical experience with them and I did not want to pull the topic too strongly towards non-C++11. I mainly added Boost's shared_ptr and scoped_ptr as a bridge in case shinylane remembered those from the time he was working with C++11.
It also allowed me to drop C++11 as a search keyword into the post. If you were used to C++ being mostly static and unchanging (as it was pretty much for well over a decade) being pointed into the direction of newer standards is probably helpful for reentry. That said: C++11, C++14, C++17.

#5264576 MyClass myClass VS myClass = new MyClass()

Posted by BitMaster on 02 December 2015 - 06:23 AM

std::auto_ptr are deprecated. They still exist but are scheduled to be completely removed in the forseeable future. Their semantics are extremely weird and they are likely to cause more problems than they solve when not used exactly as intended (and putting them into a container was never intended).

std::shared_ptr is copyable and can be stored in standard library containers without any problems. When stuck on a pre-C++11 compiler boost::shared_ptr can be used to get basically the same functionality.

std::unique_ptr is not copyable but it is movable and can be stored in standard library containers. When stuck on a pre-C++11 compiler there is no really good alternative since they rely on rvalue references. Boost has boost::scoped_ptr but it's not really a good replacement and does not work in containers.

In a lot of cases you will want to avoid using new/delete in favour of std::make_shared/std::make_unique.

Note also that while a lot of people call it 'the STL' that name is in fact incorrect and it refers to the first pre-standard suggestion for a C++ standard library.

If I populate an STL collection with a large number of objects, I currently use 'new' and 'delete[]', but reading above has me concerned.

I suspect that is just a simple typo but this has always been an error: anything allocated with 'new' needs to be deallocated with 'delete'. Anything allocated with 'new []' needs to be deallocated with 'delete []'. Mixing the two in any way is a big error. It usually did not show any symptoms on MSVC but was never healthy and actively failed on other compilers.

#5264397 Casting a vector of arrays

Posted by BitMaster on 01 December 2015 - 05:58 AM

Once again I think we have reached a point in a discussion where I would strongly suggest you take a step back to calm down instead of continuing to ramble on in anger and other emotions as happened in so many threads in the past.

#5264392 Casting a vector of arrays

Posted by BitMaster on 01 December 2015 - 05:42 AM

it is just that pushing code fetishes over cpp is pointless).

As someone who earns his living working in C++ codebases of considerable size and complexity and sins: no. This is no "pushing fetishes". Not sticking to rules like that is a direct cause for countless lost hours.

#5263773 Casting a vector of arrays

Posted by BitMaster on 27 November 2015 - 02:03 AM

but this gives me an error when trying to compile. It says something about invalid static cast from std::array... aka{unsigned char *} to char*.

Always copy and paste complete error messages. Never "something" an error message.

That said, unsigned char and char are distinct types. So are pointers to these types. You need to be more exact what you cast to what.

Edit: You need reinterpret_cast to change the pointer types.

#5261722 simple java question

Posted by BitMaster on 12 November 2015 - 01:23 AM

Edit: not worth a fight and I'm under enough stress without opening a can of worms and arguing exact semantics and explanation methods.

#5261485 Generic Installer - Cross Platform

Posted by BitMaster on 11 November 2015 - 01:46 AM

I would just like to agree with the above. I have never encountered an installer generator across multiple platforms (as distinct as Windows, MacOS and Linux) and I would be surprised if there was one. Pleasantly surprised, but still surprised.

CMake (via CPack) for example can abstract that away up to a point, but it still uses NSIS on Windows, Bundles on MacOS and I'm-not-really-sure-what on Linux. You are still going to need significant platform-dependent settings and polishing though.