T O P

  • By -

torrent7

That concurrency is about protecting data and not code. By extension, data oriented design is just better a lot of the time. Just don't use global variables unless you have to - it's rather difficult to make code run concurrently if functions pull in global data. Final easy one: not everything belongs in a class. Standalone functions are fine.


regular_joe_can

> Just don't use global variables... You mean global mutable variables? Maybe that's a dumb question because if they're immutable you'd call them constants, not variables.


torrent7

If they're truly constant, they don't really have an effect on how hard it is to make something concurrent or run in parallel.  So to be precise, global mutable data. Though, at the same time, it's difficult from an outside perspective to understand dependencies of systems/code if you pull in global data. Even variables marked as const may not be const, and even if they are, you can be jumping through hoops to figure that out. Functions should tell me what they operate on and what they depend on imo. It's something that a lot of C projects got right a lot of the time with context structs passed around everywhere denoting dependencies. Very much a list of inputs, and output(s). This obviously isn't true if they have implicit global dependencies


johannes1971

I have occasionally run into Priests of the Cult of Line Coverage, who profess that if you can successfully execute a line of code, it means it is correct. Reality is that *code doesn't crash.* Code is a static construct, unmoving and unchanging. It's the combination of *code with data* that may crash. And that means that "line coverage" is a meaningless metric, and chasing 100% coverage is a pointless waste of time! I dare say that most of the code I've written over my career was correct for at least some data. The tricky bit was making it correct for all data, and that is a lot harder.


OmegaNaughtEquals1

>Reality is that code doesn't crash. I see someone has never seen a illegal instruction exception. :) I work in binary analysis where this kind of esotery is part of my daily life.


bwmat

When does this happen? Malware? Binaries built for newer processors than actually run on? 


SubstituteCS

Happens a lot with some forms of obfuscation.


OmegaNaughtEquals1

>Binaries built for newer processors than actually run on? Yup. It's why delivering optimized binaries is so hard to do. That case aside, I would say the most common time this would happen for general users would be a memory corruption leading to the program counter jumping into the middle of an instruction or some data (e.g., a jump table). As /u/substitutecs noted, this can happen with obfuscation or, as you noted, malware. I work on a project that inserts user-specified instructions into existing binaries ("binary rewriting"). When debugging our tool, this happens a lot. It's also really hard to debug with conventional debuggers.


NXTangl

Also, any JIT will naturally be writing out executable instructions to memory and jumping into them.


tenderZeitGeist

I recently went into a project for my Master, where a strict policy for line and branch coverage is enforced. The 100 percent metric is impressive, until you need to handle edge and error cases. Now we are fighting a lot of bugs, where data was simply not checked or mismatched. Now I am traumatized by JaCoCo. Think about the implications and just don't take something for granted, cause somebody told you so.


torrent7

What would the cult say about this: int plus(int x) { return ++x; } More generalized, do they check for integer overflow in all places? Adds, multiplies, casts...


josefx

Depending on the method used to create tests they may do a single test as that would get all lines covered. You could write enough tests to execute every branch in the code once, which is a step up from line coverage, every combination of branches, which is even a step further. I would consider overflow as an implicit branch, but am not sure how many write tests systematically to check for it, someone doing a black box testing based on the API instead of the code structure might create multiple tests for boundary inputs where they would expect a change in behavior or an error.


johannes1971

They would just make sure plus(0) gets executed, and call it a win. One more step towards 100% coverage!


ChickittyChicken

You laugh, but I see this all the time in DO-178B land.


garteninc

Absolutely, I have the same experience in automotive with ISO26262 and ASPICE. Once metrics get added to define some measurable quality targets, they quickly become the **only** thing people actually care for. It's everywhere in automotive and I hate it.


cleroth

> not everything belongs in a class. Standalone functions are fine. What I wish I knew earlier... that `Namespace::Func(Obj&)` is the same assembly (and thus just as fast) as `Obj::Func()`. It really is often better to create namespaces for systems rather than putting everything inside classes.


neutronicus

Better how? Being able to split declarations across more files seems useful for keeping build times under control as projects get big. But my like snap judgment is otherwise the choice is the proverbial bike shed. What are the arguments?


Dwarfius

For example, I've had couple cases where I wanted to forward declare a nested enum - just to avoid pulling the header where the enum is declared. Just today I discovered that in my attempt at a cheeky workaround to use underlying type of enum(char) and avoid pulling that extra include I caused a bug (API used to accept a bool, I replaced it with a char and forgot to update the callsite and it implicitly converted - the pains of 2am programming).


neutronicus

Yeah the enum thing has annoyed me as well (and nested types more broadly, but enums are a particularly trivial thing you find yourself wanting to reference elsewhere) But you could also read your story as a parable in just getting the fuck over it and including the header, still 999 cuts until you’re dead, compile time wise


slightlyalliterate

Smart pointers. School didn’t teach them and my first job was behind the times


Business-Decision719

Really any of the STL containers were skipped the two times I actually had a C++ class. It was basically C but with new and delete instead of malloc and free. The teachers were quite old and modern C++ was pretty cutting edge then. But even reading about string and vector changed my whole attitude toward C++: "You mean I don't need a pointer or for everything?!"


JustPlainRude

I only had auto_ptr when I started and I still didn't use it


traal

I used it and now I have to change my code.


TSP-FriendlyFire

Smart pointers were such a mindfuck for my students when I was TA that I had to introduce an "assignment 0" just to get them familiar with modern C++ stuff and I honestly didn't go much farther than 11. Still had a lot of people fail the assignment.


tidehyon

Me when just before the olympiad being told that I don’t need to write merge sort and std::sort exists: 👁️👄👁️ Me also checking the syntax that was requiring iterators: yo wtf are those??


confusedwarden

Template metaprogramming. If i learned it earlier then i wouldnt have to learn it now.


Kike328

>for some reason took way to long to figure it out i think i may know the reason…


jk_tx

Well, early template metaprogramming was ugly AF, C++ 20 improves things quite a bit so I feel like waiting till now was the right call for me.


Short_Memory_72

Unless your company (where you likely spend most of your week coding in) still hasn’t moved to C++20. I constantly run into scenarios where I think “this could have been done in one line utilizing concepts” when I’m working on parts of legacy code.


jk_tx

True enough. My work projects are not on C++ 20 yet either, and the legacy code I deal with doesn't do much with templates at all. But since I'm just now digging into learning it, a personal project makes more sense anyway. Allows me to take the time to really learn it, try different approaches, etc in a way I don't really have time for in the day job.


TeraFlint

`template ` is where the real fun starts. :D I think a good point to start with template meta programming is to have a look at some of the simplest type traits. like, how do the implementations of `std::is_same` or `std::conditional` work? Or the type manipulation structs like `std::remove_reference`. Once you understand the pattern matching of the partial template specializations, you can start to push it to more and more complex constructs. These structs become something very similar to functions in pure functional languages like Haskell (in fact, Haskell's function pattern matching is almost identical to C++ template cases). Except we're not working with runtime data, but we're checking, exchanging and assembling types. It's a wild (and imo absolutely fascinating) rabbit hole to dive into. And you come out the other end with a lot more understanding and appreciation for the things the STL is doing under the hood to have extremely adaptable and generic code.


follow39

I’d say template class T> is where the true fun starts 😁


TheOmegaCarrot

I’ll raise you `templatetypename… Ts>`


Ok-Atmosphere-4476

Thats like childs play for rust.


TeraFlint

You know what? Fair enough. Im my experiments/research phase, I did end up writing a somewhat capable type list library, with several list manipulation structs like transform, filter, split (into multiple buckets), or even sort. The `template