Archive for July, 2012

Coding conventions

Posted in Coding on July 30th, 2012 by MrCranky

Another mini-rant on coding this week, originally composed as a response to someone who didn’t see why conforming to coding standards was such a big deal. In this case (roughly sorting header #include statements alphabetically) the defence was “it’s trivial to do that automatically, so why should you care whether a coder does it themselves?” That’s a pretty typical response, but the answer to it for me sums up exactly why following conventions is important, and it is nothing to do with the conventions themselves, and everything to do with how you work as a team.

First off I’d agree that this case in particular is not a major issue. None of them (indenting conventions, space conventions, capitalisation conventsion) are, but that isn’t why it gets people worked up when one coder decides to go ahead regardless. The problem is that you have a choice between:

  • Original coder does it as agreed first time

or

  • Original coder decides to ignore convention previously agreed on
  • Entire team endures negative effects of said change until either:
    • Another coder takes time out from whatever else they’re doing to fix it:
      • If they do it as part of a commit they’re already doing, it obscures the diffs for the ‘real’ changes they’re making.
      • If they do it as a separate commit, they’ve got to take the time to make sure that they’ve not accidentally broken something everyone chooses to leave it as it is and over time the entire codebase degenerates into a collection of such issues
    • Somebody writes an automatic tool to fix the problem

Fixing it after the fact is not a good solution, because it’s far more expensive than just doing it right the first time. If there’s a policy, then everyone should stick to it. If they don’t agree with the policy, then they should take that up amongst the team, not just ignore it because they don’t agree and they expect someone (or something) else to fix it later. If it’s a stupid policy, then the team can agree to get rid of it. If it has merit for others then they should respect that even if they don’t personally agree with it: because they’re working as part of a team, not just as individuals, and that should entail a certain amount of respect to your team-mates.

Most of us will have known ‘renegade’ coders, who go off into their own zone and implement some big bit of functionality without consulting with the rest of the team. Sometimes that works well, and other times they come back, throw the code over the fence at the rest of the team and act surprised when they have problems integrating it. That is no way to work, and not only will it lead to friction amongst the team, it also generally means a bunch of wasted effort that could have been avoided with better communication up front. Not respecting coding conventions isn’t nearly as bad as that, but I feel like it’s the first step down the road towards it.

When you’re working in a team, you don’t have the luxury of implementing things in a bubble: you have to work with other peoples’ code, and they have to work with yours. Coming to a common agreement as to how to work with each other is the most basic part of that, otherwise you’ll find yourself working at odds with each other. There can and should be compromises to get to that agreement, but ‘agreeing to disagree’ is generally not a viable option.

Conflicting ideas about the size of STL strings

Posted in Coding, Technical Guidance on July 18th, 2012 by MrCranky

This post is one of those “I couldn’t find it when I was Googling, so here’s a succinct description of the problem / solution so other people can avoid the same round-about research.”

Symptom:

You have one bit of code (perhaps a library or a DLL) which thinks that sizeof(std::string) is 28 bytes, and another bit of code which thinks that it is 32 bytes. In Release mode they both agree that the size is 28 bytes. In our case it was actually std::wstring, but both string objects are actually the same size and exhibit the same problem.

Diagnosis:

You have a mismatch in your configuration between the two projects, essentially you’re trying to mix Debug code and Release code, which is just fundamentally not allowed. This much information is readily available on the Internet with some basic searching, but crucially most of those places don’t tell you the one piece of information you really need: exactly what setting is different? Which one of the dozens of settings that typically differ between Debug and Release is the STL code actually paying attention to?

The real answer lies in the details. It is not a Debug vs Release problem (well it is, but only indirectly). If you’re like me, the first thing you checked was the presence (or absence) of the _DEBUG or NDEBUG pre-processor directives. After all, they’re the defines most often used to get differing behaviour between the debug and release builds. You’ll find however that those definitions have no bearing at all on the size of std::string.

Now is probably a good time to visit this Stack Overflow question which links to good information on the subject.

In fact, the root cause is the presence and value of the preprocessor definitions _SECURE_SCL and/or _HAS_ITERATOR_DEBUGGING. If these are defined and set to 1, then sizeof(std::string) will be 32. If they are defined and set to 0, sizeof(std::string) will be 28.

More troubling is that even if those definitions aren’t explicitly listed in the set of pre-processor definitions, I believe the compiler (the Visual Studio compiler at least) will define them for you, based on its own internal logic. _SECURE_SCL will always be 1 for both debug and release builds, but _HAS_ITERATOR_DEBUGGING will be 1 for debug builds, 0 for release builds (as it has a tangible performance impact). You can explicitly turn off _SECURE_SCL to get more performance if you want, but you should understand the drawbacks before you do so.

I will update this post if I find out more about the internal setup of those definitions, but simply knowing that they are the cause of the size difference is usually enough to get to a resolution. I would certainly recommend adding some logging to both code modules that spits out the value of these two defines so it’s clear to you what the values are on both sides.

Resolution:

For most, an immediate solution is to simply manually define iterator debugging to be on or off in both projects so that they are consistent. To do that, simply add _HAS_ITERATOR_DEBUGGING=1 (or 0) to your project’s preprocessor definitions.

You may want to avoid setting it explicitly (ideally you’d simply rely on the compiler defaults), in which case you’ll need to figure out why iterator debugging is enabled for one module but not the other. For that I’m afraid you need more information about how the compiler decides to set those defines, but presumably another one of your project settings is indirectly making the compiler decide that iterator debugging should be enabled or not, and it is that setting which is different between your two modules.


Email: info@blackcompanystudios.co.uk
Black Company Studios Limited, The Melting Pot, 5 Rose Street, Edinburgh, EH2 2PR
Registered in Scotland (SC283017) VAT Reg. No.: 886 4592 64
Last modified: February 06 2020.