PDA

View Full Version : What do you guys think about this?



RobR
06-02-2006, 01:48 PM
And now for something totally different... At the weekend, I spent some time chatting to a (software) development manager for a sizeable public company. He spends a lot of his time trying to persuade his coders to stop using C/C++ contractions. Without prompting (he's nothing to do with the OU!) his reasons are:

1. They do nothing for optimisation in these days of good optimising compilers.

2. The can severely reduce readability and maintainability; this last is his chief concern as well over 50% of their work is maintaining old code (and some of the other 50% is working out how to hook in enhancements requested by users).

3. With some libraries, they can severely damage the code semantics.

The moral is: don't use ++ (pre or post), +=, -=, or any of the other <something>= contractions. Don't use "zero means false, non-zero means true"; if something is a boolean, use bool; don't use statements in conditional statements; don't use the fact (C/C++ peculiarity) that assignment statements have a value; use while when you mean a while loop and for when it really is a for loop;


while (true)
{
...
if (...) break;
...
}


is a total no-no; etc., etc.

Rant over (for now).

Posted by one of the OU tutors, and reproduced here with his permission.

I'm not experienced enough to comment, but does ++ and += really obfuscate code that much?

dwks
06-02-2006, 01:53 PM
No, quite the opposite. i += 5 is the way you think. You think "add 5 to i", you don't think i = i + 5, "get i, add 5 to that value, assign the result to i". I think it makes the code easier to read.

Prelude
06-02-2006, 01:58 PM
>but does ++ and += really obfuscate code that much?
No. People who find it confusing when used properly likely don't know the language as well as they claim. This seems like a blanket ban on features that have the potential for abuse, which is stupid.

RobR
06-02-2006, 02:03 PM
Should have perhaps mentioned that the OU (Open University) course I'm currently doing insists on i=i+1 instead of i++...

Thantos
06-02-2006, 02:07 PM
Whenever I write code, regardless of the language, I try to use the operations that make since and aid in reading of the code.

To me ++ and -- mean to go on to the next value/item or return to the previous value/item.
So I use them in that context. Sometimes doing:

obj = obj + 1; doesn't really make a lot of sense. For example lets take the often misunderstood pointer arithmatic:


int x[10] = {0,1,2,3,4,5,6,7,8,9};
int *ptr = x;
ptr = ptr + 1;

Now for those of us that have studied it that bit of code doesn't confuse us. However take a newbie and show them that code and they'll look at you crossed eyed and drooling. I know because I've seen it in those that I've tutored.
Now if you were to show them this:


int x[10] = {0,1,2,3,4,5,6,7,8,9};
int *ptr = x;
ptr++;

Most would understand that ptr is now pointing at the next element.

Now onto += and the like. The real benefit is not having to type out the name twice and taking the risk of mispelling it. I see nothing wrong with using them as they are very clear in their operation.

As for your while loop example, it might not be the prettist but sometimes it can be the best.
For example say you have a main loop in your program that does the processing as it becomes available. Half way through the middle of the loop you have some type of exit condition (maybe due to an exit code or fault). Now this condition doesn't exist at the beginning of the loop. So where do you place the conditional?

With a few expections for things like gets() pretty much anyone who says not to use a tool needs to be shot. Just because they are too stupid to know how to use the tool properly doesn't mean its a faulty tool.

Perspective
06-02-2006, 02:33 PM
i += i++ + ++i; wheeeeeeeeeeee!



*no, there isn't really a point to my post. I think += and all that jazz is perfectly readable and should be used in any way except the above.

Mario F.
06-02-2006, 03:08 PM
++ and --: I don't think he can defend his point of view on this one. Since when obj = obj + 1 is more obvious than ++obj or obj++?? Especially when dealing with pointers and iterators? They are called incrementing operators for a reason. And they are not specific to C++. They are so widely use that what seems strange is not seeing them on any line of code.

Some terse statements in C++ are so widely used that it simply seems strange not seeing them anywhere: *p++;

The alternative involves two lines of code and twice the chance of typos.

+= and it's brothers: This one is a bug killer. How many times do I forget to properly include everything within parenthesis on more complex expressions on the right hand operand. Now... let's add another pair of parenthesis because my boss likes obj = obj + something better :)

0 for false: Some functions simply cannot return a bool. They need to return an arithmetic type and that type needs to be checked for validity. The alternative would be to either set a global variable or add a referenced bool to my argument list. No thank you.

Besides both the standard library and the STL rely heavily on 0 for false and everything else for true. Unless he doesn't use these two libraries anymore he has no choice than to swallow this one :)

I would like to know too how he thinks about checking for NULL. Is this also a no-no? I suppose...

break statements: What do you call a loop without break and continue statements? A boring loop which has no imagination and can only be tested for one condition. In short, a poor loop. I prefer richer loops than can be tested for more than one condition.

whiteflags
06-02-2006, 03:15 PM
In general, smacking the B&* hammer on a feature of any language is a stupid idea; claiming something cannot be used forever. Take your teacher's advice with a pinch of salt.

B& = banned, for non4channers

itsme86
06-02-2006, 04:12 PM
WTF is a 4channer?

itsme86
06-02-2006, 04:13 PM
WTF is a 4channer?

Anyway, agreed. This "developer" sounds like a moron.

JaWiB
06-02-2006, 04:50 PM
Those sound like some pretty dumb pet peeves to have.

>>use while when you mean a while loop and for when it really is a for loop

I don't see how this could be a big problem. I mean, it wouldn't make much sense to do:


for(;condition;)
{
}

But it doesn't seem that much less readable than the while loop to me. (And I don't think I've actually ever seen anyone do this.)

I guess I could see a problem between using do...while and while or for, but I'd be surprised if that was a common mistake.

gcn_zelda
06-02-2006, 05:31 PM
However, I've seen some novices use:



int condition = 1;
while(condition == 1)
{
:here

// do a tap dance. get user input. if user pushes 1, condition = 1.

if(condition != 1)
{
goto here;
}
}


Or something like that. (I haven't programmed in forever.)

VirtualAce
06-02-2006, 11:13 PM
So basically take out all the cool things you can do in C/C++ for the sake of readability. It would increase the length of the code, hamper readability, and look more like BASIC than C/C++.

Nothing wrong with:



if (FAILED(GetDevice())) DoSomething();

laserlight
06-02-2006, 11:17 PM
The can severely reduce readability and maintainability; this last is his chief concern as well over 50% of their work is maintaining old code (and some of the other 50% is working out how to hook in enhancements requested by users).
From what I see, when they are used correctly as expressions of concepts, they can enhance readability and maintainability. Like what Thantos wrote: "To me ++ and -- mean to go on to the next value/item or return to the previous value/item." Likewise, "x += n" would mean something like "advance x by n places". But "x = x + n" means "advance x by n places, assign result to x". It (probably, and should) does the same thing as "x += n", but the meaning is not exactly the same.


I would like to know too how he thinks about checking for NULL. Is this also a no-no? I suppose...
Well, it is true that there is no need to check for NULL before doing a delete.... :P

whiteflags
06-02-2006, 11:41 PM
WTF is a 4channer?Anyone who posts on the 4chan forums is a 4channer.

VirtualAce
06-03-2006, 03:18 AM
Well, it is true that there is no need to check for NULL before doing a delete.... :P


Still not implemented in MSVC .NET 2005. Calling delete on a NULL pointer will cause an exception. I know it's not supposed to be that way, but then when does MS listen to anyone but themselves?

Sang-drax
06-03-2006, 05:06 PM
I agree on the true/false vs. 1/0 issue.

Still not implemented in MSVC .NET 2005. Calling delete on a NULL pointer will cause an exception. I know it's not supposed to be that way, but then when does MS listen to anyone but themselves?
What? This compiles and runs fine in 2005:

int main()
{
delete (char*)0;
}

joeprogrammer
06-05-2006, 09:42 AM
>>i += i++ + ++i; wheeeeeeeeeeee!

Haha, Perspective, I like your point of view :)

novacain
06-06-2006, 10:43 PM
As I am now the person evaluating programmers this company will hire, I can tell you that I would consider this a black mark against you (if I was interviewing you).

Its not your teachers job to make the language/code simpler. Its your teachers job to ensure you can handle any programming task put before you. Even if that means knowing where/when to ask for help.

>>Should have perhaps mentioned that the OU (Open University) course I'm currently doing insists on i=i+1 instead of i++...

Great, so when you get out into the real world, find that all C++ code contains these operators, you will be have difficulty reading it (as opposed to someone who was taught to use them).

Its not like all the code that contains these operators (or the programmers who wrote it) are going away soon.

If something as simple (IMHO) as as these operators confuses you then you are going to have issues reading 'real world' code.

RobR
06-07-2006, 09:41 AM
Erm, I wasn't stating my original post as my opinion, or implying that I was confused by it. What precisely is it that you would see as a black mark against me? There's nothing actually wrong with i=i+1, just as there's nothing (as far as I can see) wrong with i++.

Please explain :)

laserlight
06-07-2006, 09:47 AM
What precisely is it that you would see as a black mark against me?
I think novacain's reasoning is that since your teachers teach in this way, the students are likely to be unable to deal with real world code. You thus will be lumped in that category (of probably incompetent programmers), even if you are actually different.

RobR
06-07-2006, 10:04 AM
Some justification, again quoted. (MT262 is the course I'm doing currently). To be fair, the course isn't a C++ course as such, it's more a general programming principles course that happens to use C++.


C++ has #defines which can look like functions:


#define squareit(x) (x*x)

Then you can use it to square numbers:


int MyInt;
int NumberThree;
NumberThree = 3;
MyInt = squareit(NumberThree); // Now MyInt has the value 9.

BUT some programmers combine ++ and 'function' calls.

These clever people would write


MyInt = squareit(NumberThree++);

and would expect MyInt to be 9 and NumberThree to be 4. Instead, MyInt would be 9 but NumberThree would be 5, try it if you don't believe me :-)

Moral: don't use ++. Ok it is safe in some places, but explaining exactly where is beyond MT262.

BTW You don't know what (in a library) is a genuine function and what is a macro, and they can and do change over time. Code gets broken that way.

joeprogrammer
06-07-2006, 10:08 AM
Actually, if you can, use i++ instead of i = i + 1. I read somewhere that using i++ actually results in more optimized code; the assembly code simply uses incr (or whatever it's called) instead of all that other stuff.

RobR
06-07-2006, 10:15 AM
>> I read somewhere that using i++ actually results in more optimized code

I could be wrong, but I doubt that.

laserlight
06-07-2006, 10:19 AM
Moral: don't use ++. Ok it is safe in some places, but explaining exactly where is beyond MT262.
Actually, I think that the moral in this case is to avoid macros as pseudo-functions. If it was an actual (inline) function, the use of ++ would not be a problem here.

For example, the code would also fail in:

MyInt = squareit(NumberThree + 1);
Since that would be expanded to:

MyInt = NumberThree + 1 * NumberThree + 1;
which leads to:

MyInt = NumberThree + NumberThree + 1;

The more correct macro definition would be:

#define squareit(x) ((x)*(x))

Prelude
06-07-2006, 10:19 AM
>I read somewhere that using i++ actually results in more optimized code
In C++, this can easily be the case with classes that overload the operator. For primitive types, you can expect identical machine code from i=i+1, i+=1, ++i, and i++ when used as standalone statements. Anything less would get a compiler laughed out of business, since this is a supremely trivial optimization.

Dave_Sinkula
06-07-2006, 10:22 AM
Moral: don't use ++. Ok it is safe in some places, but explaining exactly where is beyond MT262. Some canned example:
int x = getc(f++);
[Warning 666] Expression with side effects passed to repeated parameter 1 in macro 'getc'Moral: choose good tools.

Mario F.
06-07-2006, 10:56 AM
Moral: don't use ++. Ok it is safe in some places, but explaining exactly where is beyond MT262.

It's beyond MT262 because they cannot justify this.

It is sadly ironic that a programming course uses what is widely considered bad practice (macros) to justify the removal of a style that is widely considered a standard and good practice (increment and decrement operators).

It's sadly ironic and ridiculous.

laserlight
06-07-2006, 11:17 AM
It is sadly ironic that a programming course uses what is widely considered bad practice (macros) to justify the removal of a style that is widely considered a standard and good practice (increment and decrement operators).
haha, I checked out Stroustrup's technical FAQ on macros, and what RobR's tutor mentioned was indeed an example, except that it was about... what's wrong with using macros (http://www.research.att.com/~bs/bs_faq2.html#macro).


One of the most common subtle problems is that a function-style macro doesn't obey the rules of function argument passing. For example:


#define square(x) (x*x)

void f(double d, int i)
{
square(d); // fine
square(i++); // ouch: means (i++*i++)
square(d+1); // ouch: means (d+1*d+1); that is, (d+d+1)
// ...
}

The "d+1" problem is solved by adding parentheses in the "call" or in the macro definition:


#define square(x) ((x)*(x)) /* better */

However, the problem with the (presumably unintended) double evaluation of i++ remains.