|
Yeah, but that's not what I was talking about.
More I'm talking about things like this.
if(pin_d1>31) {
b |= (((pins_h>>((pin_d1-32)&31))&1)<<1);
} else if(pin_d1>-1) {
b |= (((pins_l>>(pin_d1))&1)<<1);
}
if(pin_d2>31) {
b |= (((pins_h>>((pin_d2-32)&31))&1)<<2);
} else if(pin_d2>-1) {
b |= (((pins_l>>(pin_d2))&1)<<2);
}
if(pin_d3>31) {
b |= (((pins_h>>((pin_d3-32)&31))&1)<<3);
} else if(pin_d3>-1) {
b |= (((pins_l>>(pin_d3))&1)<<3);
}
if(pin_d4>31) {
b |= (((pins_h>>((pin_d4-32)&31))&1)<<4);
} else if(pin_d4>-1) {
b |= (((pins_l>>((pin_d4)&31))&1)<<4);
}
if(pin_d5>31) {
b |= (((pins_h>>((pin_d5-32)&31))&1)<<5);
} else if(pin_d5>-1) {
b |= (((pins_l>>(pin_d5))&1)<<5);
}
if(pin_d6>31) {
b |= (((pins_h>>((pin_d6-32)&31))&1)<<6);
} else if(pin_d6>-1) {
b |= (((pins_l>>(pin_d6))&1)<<6);
}
if(pin_d7>31) {
b |= (((pins_h>>((pin_d7-32)&31))&1)<<7);
} else if(pin_d7>-1) {
b |= (((pins_l>>(pin_d7))&1)<<7);
}
How many of these if statements will be compiled into the binary?
You can't know that just by looking at it, assuming this is C++.
In this case, none will, because they all evaluate constexpr values.
But those can be buried under templates, for example, and then the answer non-obvious.
Real programmers use butterflies
|
|
|
|
|
From 1985 to 2010, any decent run-of-the-mill-general-purpose coding standard worked pretty well for C and C++. But since C++11, every batch of new features also added more tools that were easy to misuse against the spirit if not the letter of said guidelines.
Nowadays, the only way to maintain good code with modern C++ is using modern standards following Clean-Code / SOLID principles. I've found the most important thing is keeping classes and functions small: just one purpose is the key. The best way to find out if your function or class is small enough is thinking about a name that describes it well: if a good description requires an 'or' or 'and' or 'then', then your class or function tries to fulfil more than one purpose and should be split!
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
|
|
|
|
|
"draw::text<>" has one purpose in my draw class in GFX, and has multiple overloads, the implementation of which spans several functions and one entire private header+cpp file. Because it renders truetype text. Even after factoring the function is half a screen on my display.
I agree with you in principle, but in practice I can't code that way. I have some wiring issues in my head that affect my short term memory, and if I over-factor I forgot how to navigate all the layers and calls. In some respects my condition can be debilitating. This is not one of those areas, but it does mean I have to adjust my approach. Cognitive load on the other hand, I can take for days. So give me a long function, as long as its purpose is singular.
But I understand that this is less than ideal, because I code professionally, and have coded on teams, from PM to lead to QA.
That's one reason I'm not a stickler for industry wide standards. I think a good coder can pick up a standard someone else uses, as long as that someone was consistent, and it's not awful - like there's sense to it. I mean, I have to consider myself and that I'm probably not the only one coding with a handicap of sorts.
As far as C++11 and beyond, I agree with you. But also I'm going to be difficult here - the introduction of variadic template arguments and things like that which facilitate metaprogramming and the metaprogramming itself creates its own kind of maintenance monster.
When you get used to reading "metaprogrammed" C++ it gets easier, but it's still a beast. I've had to reimplement a lot of what the STL hides at points because I target frameworks where the STL is partial if at all, and I don't know which parts are necessarily available, so I understand the sausage making therein.
On the other hand, you can do so much with it. Opening a dialogue with the compiler using your code, so that it can shape the generated code is just ... no other coding is like that. It sets C++ apart, and allows you to do some truly amazing things. In GFX I allow you to define pixels with arbitrary binary layouts and color formats. It then lets you manipulate all the individual color channels and if everything is const, it all resolves const. That means if you use a predefined color like "hot_pink" (an X11 standard color) it will resolve to a single scalar const value at compile time. You can even get the compiler to color blend and convert color formats (from like Y'UV to RGBA or BGR)
All that with C++14 and a somewhat byzantine header file (linked if you're curious) gfx/gfx_pixel.hpp at master · codewitch-honey-crisis/gfx · GitHub[^]
Anyway, you can't do that with C++ prior to 11 (14 in this above case), and you can't do it really in any other language, at least not as directly. (C# includes some code generation facilities now, but that's roundabout)
Real programmers use butterflies
|
|
|
|
|
I'm working on a series of "How to Write Code to Solve a Problem, A Beginner's Guide" articles to cover the bits learners seem to have the most problems with*. So fare I've covered the "break the problem into smaller pieces" approach to getting started, and syntax errors.
And the next one is a biggie: Debugging.
And there is my problem. To show how to debug something I need to write some short-ish code with a small, subtle bug in it, prove it has a bug, and then show how to fix it.
But ... have you ever tried to deliberately write code with a bug in? It's not as simple as I thought it would be ... In fact, I'm finding it a lot harder to write buggy code than I do to write good code!
* Other than being told "no, I won't do your homework for you" of course. Or maybe I should write one of those ... Hmmm.
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
modified 16-Feb-22 8:45am.
|
|
|
|
|
Make a fencepost error. Make something one based, and then don't one base it elsewhere in your code.
Real programmers use butterflies
|
|
|
|
|
As h-t-c said, an off-by-one.
Or an extra semicolon on an if() or for() - can make the point that the compiler doesn't give a toss about your pretty indentation when determining control flow.
Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012
|
|
|
|
|
So you're writing a book? 'cause that's what ends up happening when you go down this rabbit hole.
|
|
|
|
|
One more
- Missing variable initialization
|
|
|
|
|
How about NullPointerException? That seems to be one that so many people do not even understand what it's about.
|
|
|
|
|
Two different variables, with much too similar names - and then using the wrong one.
My_Increment
My_Decrement
|
|
|
|
|
Something like this. Includes missing out on floor, ceiling and index and more.
List<double> values = new List<double> { 1, 2, 3, 4, 5, 6 };
double percentileToFind = 0.90;
int indexToLook = (int)Math.Round(values.Count * percentileToFind);
double startingValue = values[indexToLook];
percentileToFind = 0.95;
indexToLook = (int)Math.Round(values.Count * percentileToFind);
startingValue = values[indexToLook];
"It is easy to decipher extraterrestrial signals after deciphering Javascript and VB6 themselves.", ISanti[ ^]
|
|
|
|
|
Using the debugger is an admission of defeat. A option of last resort (just short of actually asking for help).
modified 16-Feb-22 9:16am.
|
|
|
|
|
Division by 0, array index out of bounds, null values?
"Go forth into the source" - Neal Morse
"Hope is contagious"
|
|
|
|
|
var vAux = 'whatever...';
if (vAux = null && vAux = undefined && vAux.length = 0)
console.log('Error at ValidationCode!');
|
|
|
|
|
I think one point that is often missed in teaching coding is making sure you can show that your code is correct. Not necessarily TDD, but setting up some input that you know what the output should be.
This is very helpful in understanding the problem, and helps you know when you are done.
"Time flies like an arrow. Fruit flies like a banana."
|
|
|
|
|
I'd agree - and one of the planned articles is all about testing. I'll be mentioning it in "Debugging" but not to any depth.
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Cut and paste errors
x = x + 1;
y = x + 1;
(Slightly more complicated would be better)
Because your brain sees what it wants. Not what is there!
(My sons first comp sci program. He didn’t see it. I didn’t see it. but stepping through the debugger sure made it obvious!)
If you can't laugh at yourself - ask me and I will do it for you.
|
|
|
|
|
Infinite or range-error loops e.g while(test = 1) or for(i = 100; i > 0; ++i) I know I'm guilty of both of these, on occasion.
Keep Calm and Carry On
|
|
|
|
|
k5054 wrote: Infinite
and put a short counter on it so that it doesn't completely blow up!
"Go forth into the source" - Neal Morse
"Hope is contagious"
|
|
|
|
|
We / I learned how to flowchart before learning to write code. Don't know how you get to one without the other (at some point), without a lot of "explaining".
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
Comparing for equality two real valued calculated results, which should mathematically be identical, but due to limited precision, they differ in the least significant bit (or two).
If you were working on old machines using 1-complement integer representation, you could also compare plus and minus zero for equality, but I haven't seen a 1-complement machine for quite a few years now.
A related one: When casting (implied or explicitly) to a longer word length, will the upper bits be zero or sign bit filled? Note: This can be both language/datatype and machine architecture dependent. I once spent half a day to understand a single if(x>y) statement: Both alternative seemed to do exactly the same, just in slightly different order. The reason was an implied cast (from 8 to 16 bits - this was on an 8051) where "wrong" sign extension would wreck the result if the same order of execution was used in both cases.
Edit: This was intended as a reply to the OP, not as a reply to Gerry.
|
|
|
|
|
Using iterative instead of declarative statements to manipulate collections using Linq??
|
|
|
|
|
|
I'm not sure this can be done anymore, declare a global variable DateTime as an int. Worked in VB (possibly 6) and truly screwed up an application.
Never underestimate the power of human stupidity -
RAH
I'm old. I know stuff - JSOP
|
|
|
|
|
I was once told to write a short snippet in C++ with a couple bugs in it. One obvious and one less obvious to give as a coding test to prospective new hires. It took me hours. Plus, I never docked a candidate that "failed" the test in an interview. And thus hold interview tests in the highest disdain.
My suggestion: An if statement with 2 indented lines under the conditional but no enclosing code block delimiters (braces).
if (x > y)
x++;
y++;
|
|
|
|