Coding-Style Poll

Started by
63 comments, last by BBeck 7 years, 6 months ago

I'm nowhere near as picky as I used to be.

Usually I use braces and member variable/function names like this:


if (mPosition.y < 0)
{
    doSomething();
}

Except I prefer not to use braces on single line if statements. Not terribly annoying, but I do think it hurts readability a bit.

One exception I make to my normal bracing style is in switch statements. Normally I don't like to use braces around cases, but if I need a variable, then I do it like this:


switch (something)
{
case 0:
    qwer();
    break;
case 1: {
    int a = 0;
    asdf(a);
    } break;
case 2:
    zxcv();
    break;
}

Not only does it save two lines, it keeps the indentation level the same without looking as funky as it does if the braces are on their own lines. But again, I could easily give it up if it went against a project's style standard.

I like the m prefix to differentiate member variables from local variables/function arguments, so it's more clear where the side effects are. And I think it looks nicer than m_ and is slightly faster to type.

Classes, structs and global functions are all upper camel case with no prefixes. I would be slightly annoyed if I had to use the C prefix for classes.

Global variables are prefixed with g, constants prefixed with k, enum values with e. I could easily be talked out of any of those, although I do think global variables should have something to mark them as the necessary evils that they are ;)

Long ago, I used Hungarian prefixes on variable names, but I hate them nowadays.

One thing that really bothers me is excessive use of single-letter variable names. It's ok for x, y, z, one or two loop iterators, and stuff like that. But it can quickly turn unreadable if you have a big equation with lots of them. That's why I like programming better than math/physics :) Use meaningful names so you don't have to memorize what each variable is. Long names are ok, especially on things that aren't used very often.

I like spaces around operators so equations don't get too crowded looking. I'd be pretty annoyed without them.

I don't have much preference on spaces around the parentheses of if statements/loops/etc., but I usually do them like the examples above.

Tabs and spaces have plenty of potential drama. Especially if someone uses a different tab size than everyone else, and makes a big table where everything is aligned with tabs. I have a bit of OCD to make my code tab-independent, where I use tabs only at the beginning of lines, and then use spaces between tokens to align things. So even if you change the tab size, it just shifts the whole block left or right but the alignment remains correct.

Advertisement

As I posted already I don't really care about layout oriented standards. There are some i like better than others but I'll adopt whatever I'm required to with minor grumbling.

More important are standards for the code itsself.
Consistent ways of allocating memory. Consistent ways of using threads (Do we use queues, do we "ban" shared data?) Consistent ways of passing data. Do we prefer pass by pointer? Or reference? Do we prefer to allocate memory and pass it into a function to use like in C or do we let objects handle their own memory? Do we like shared pointers or do we prefer other ways to manage things?
I find all of that matters more than layout but again, as long as it's not insane I don't much care the details.

And then standards for accepting code?
Do we insist on actual proper code reviews?

Do we properly document what the changes are _for_ in source control and do we have one functional change per commit so we can manage them?
How is code deployed? Do we need to write a backout plan for each change in case it fails to work in production...

These things matter more than the detail

I find braces not on their own line very hard to read. Believe this is K&R style?


for(int i = 0; i < 10; ++i) {
       doLoopyStuff(i);
}
My brain just cannot process that. I can only handle:


for(int i = 0; i < 10; ++i)
{
    doLoopyStuff(i);
}
Professionally, I fit in with what others do but I'm fortunate that my current colleagues are "own-line-brace" guys too, as I would be at a major disadvantage if I had to write and follow code like my first example. But I suppose I'd just adjust to it.

My colleague has a very weird habit that I've adjusted to now:


class Foo
{
public:
    virtual
    const int*
    method() const;
};

const int*
Foo::method() const
{
}
End of the day, I hated this when I first saw it, but within a week or so I'd adjusted and I now flip between "work code" and "home code" without any problem whatsoever.

For the record, I know there are some tools that rely on functions being declared the latter way (type on its own line, function name on first column).

Don't pay much attention to "the hedgehog" in my nick, it's just because "Sik" was already taken =/ By the way, Sik is pronounced like seek, not like sick.

More important are standards for the code itsself.
Consistent ways of allocating memory. Consistent ways of using threads (Do we use queues, do we "ban" shared data?) Consistent ways of passing data. Do we prefer pass by pointer? Or reference? Do we prefer to allocate memory and pass it into a function to use like in C or do we let objects handle their own memory? Do we like shared pointers or do we prefer other ways to manage things?
I find all of that matters more than layout but again, as long as it's not insane I don't much care the details.

QFT. In a given code base these things should be standardised and any deviation documented (e.g. "//have to use malloc here for 3rd party lib").

This actually provides a useful guide for new developers.

if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight

I'm always doing


for(int i = 0; i < 10; ++i) {
       doLoopyStuff(i);
}

but I feel adding a line break between the function parameters and the first line helps readability for any function bigger than 5-10 lines :


for(int i = 0; i < 10; ++i) {

       doLoopyStuff(i);
       doLoopyStuff(i);
       doLoopyStuff(i);
}

So should i simply switch to the classic style ??


for(int i = 0; i < 10; ++i)
{
       doLoopyStuff(i);
       doLoopyStuff(i);
       doLoopyStuff(i);
}

The only things that annoy me are being forced to use strict prefixes for the type, over-descriptive variable names and the use of auto (where it does not improve readability). I like to read and type my code in a concise manner.

But honestly, I've been to different companies with different standards and the only thing that tends to frustrate me, is when there are partial coding standards - either we have one or we don't. I generally don't care how I'm forced to code, as long as it's well defined. (of course there are exceptions for pure idiocy)

Projects I worked on I usually had control of the format (and even when working within a prevalent style I would do ALOT of format cleanup to make the code style better when possible)

Visual scanning (eye searching) of large code files was something I always wanted to facilitate. (this is for C/C+) Ive worked with alot of intricate/complex code and my jobs usually were not just writing new code but FIXING other peoples code.

Style formats I frequently employed (always on my own projects) :

Braces that match the block they surround, brace usually on a separate line, frequently with USEFUL one liner comment about the block if more than trivial/obvious

triple space indents

'else' statements on their own line with a different offset from the if and the 2 subblocks (exception being an 'else if' )

comment LINE across page between most (non-trivial) subrountines //===================... to be highly visible (i had lots of very long subroutines)

very repeated (a grouping) of very short 'if' blocks (with their block braces) put together on the same line with the 'if' statement to compress vertically (when its doing largely the same operation

Some assignment statements - when there are many, all of the same type could be grouped more than one statement to a line, but aligned

extra blank lines added between higher level groupings of code (visually splitting up the hunks of code within subroutines)

end comment on subroutines // end of subroutine name() to allow jumping to end (of often very long routines) quickly on a search

//

//===================================================================================

//

Also for easier readability/decypherment :

complex 'if' (do-while, while ...) statements having every possible parenthesis added and blanks added between operators/operands and clauses of the same depth/type (&& ||) being indented to match and clauses often put on different lines,

equations in 'if' statements always wrapped in parens ( likewise on subroutine parameters)

Comments (a whole separate thread I'm sure ....) wherever something clever or unusual being done to be marked with a comment making it clear

short/minor comments frequently on the code line

Goto Labels having good names that make their function clear and indenting them only to be close to left edge to stand out to be easily spotted (more scan high visibility...)

local variables at start of subroutine likewise columnized type + name

subroutine call blanks after commas ',' to visually separate parameter values often one parameter per line on complex/long lists of parameter (like for directx library calls)

subroutine definitions one parameter per line (after first) lined up/columnized with type (with comment options of modal options right there if of that function)

avoidance of the ? : type of construct

--------------------------------------------[size="1"]Ratings are Opinion, not Fact
I can live with the prefixes C, I, m_, g_, etc. I can live with different brace styles, I can live with the 80-character-per-line limitation, but the one thing that gets my jimmies rustled is when I encounter the following for literally every function.


//////////////////////////////////////////////////////////////////////////////
// *-*_*-*_*-*_*-*_*-*_*-*_*-*_*-*_*-*_*-*_*-*_*-*_*-*_*-*_*-*_*-*_*-*_*-*_*-*_*-*_*-*_*-*_
////
//// NAME OF FUNCTION:
////             SetValue();
////
//// PURPOSE OF FUNCTION:
////             Sets the value.
////
//// INPUT PARAMETERS:
////             value
////                       The value to set.
// _--_--_---_--_--_--_--____-__-___-_----_--_--
//// AUTHOR: Autism McTrashWizard
//// \\\\ ==== //// \\\\ ====//// \\\\ ====//// \\\\ ====//// \\\\ ====//// \\\\ ====//// \\
void SetValue(float value)
{
    g_value = value;
}
"I would try to find halo source code by bungie best fps engine ever created, u see why call of duty loses speed due to its detail." -- GettingNifty
I can live with the 80-character-per-line limitation

I've also worked on some projects that set a 150 character line length and then made use of it almost every line, which I found way more annoying than a "short" length, since the seemingly ever longer names for things meant most lines did in fact use that length and then still wrap, to the '(', '=' or other "alignment" symbol half way across the screen.

The people I joined there just had a single code window on a 1080p screen. I on the other hand generally have the solution explorer (or similar) panel, wide enough to fit whatever deep folder structure there was, then to have 2 side by side code windows (e.g. the cpp + hpp, or the structure + builder, and such like). I found that extremely disruptive as it messed up my entire workflow.

Id go for a short length any day.

but the one thing that gets my jimmies rustled is when I encounter the following for literally every function.

The formatting or the need for a doc comment that stated nothing useful?

I've taken a disliking for coding styles that then require a large amount of additional code/text to not tell me anything a couple of words could have. Even if the basic starting point was an OK formatting (e.g. doxygen, javadoc, etc. for comments, always use braces, description names, etc.).

The idea of a formatted documentation block that stands out I quite like, its just when there these massive blocks repeating the same thing (and who even reads those later anyway?).

There also often a source of doing 3 or 4 (slow) rebuilds because the style checker found a full stop in a comment out of place. I then very frequently see simple things with just plain wrong comments and names because someone copy pasted to avoid typing so much.

e.g. builders that just set simple fields because of an immutable object rule, and 4 parameter constructor rule. Maybe OK so far if dont have C++ "const" in most languages, but then the field in the actual object, the getter in the object, the field in the builder, the getter in the builder, and the setter in the builder all get full doc comments fully describing the field.


        /**Set the name value used to build MyObject.
         * @param value fieldWithLongName value to set. Must not be null and be at least MyObject.MIN_FIELD_WITH_LONG_NAME_LEN and ... and ...
         * @return This MyObjectBuilder instance for chaining. Not null.
         * @throws NullPointerException if the name was null.
         * @throws IllegalArgumentException If the name did not meet one of the other requirements.
         */
        public @NotNull MyObjectWithAReallyLongNameBuilder withFieldWithLongName(@NotNull final String value) 
                throws NullPointerException, IllegalArgumentException {

            Preconditions.checkNotNull(value);
            Preconditions.check...

            this.namefieldWithLongName = value;
            return this;
        }

And generally such strict rules just seem to be a massive waste of time. I still come across lots of horrible code that was written to the letter of the style guide / checker. e.g. the ability to combine long repetitive names and lambda/stream features to "avoid branches" for the complexity checker to make a 10 line by 100 column solid block, then repeated 10 times for each of the different fields/arrays being processed.

Something like this...

int main()
{
	double fakeReals[10];
	int a = 10;
	void* p = &a;

	class Record
	{
	public:
		char toCh( int param, void* mem )
		{
			int8_t ch;
                        delete mem;
			do
			{
				// TODO: Add some potential bugs here!
			}
			while( param != 0 )
			return ( char )ch // Ugly!
		}
	}
}
"Recursion is the first step towards madness." - "Skegg?ld, Skálm?ld, Skildir ro Klofnir!"
Direct3D 12 quick reference: https://github.com/alessiot89/D3D12QuickRef/

This topic is closed to new replies.

Advertisement