Page 2 of 3
Re: The obvious thing I should've learned 5 years ago
Posted: Sun Jan 31, 2010 7:34 am
by Combuster
And people don't use it because GCC does not accept restrict by default. (it defaults to the '89 standard, you'll need to pass --std=gnu99 or similar for it to work)
Re: The obvious thing I should've learned 5 years ago
Posted: Sun Jan 31, 2010 9:54 am
by Synon
Combuster wrote:And people don't use it because GCC does not accept restrict by default. (it defaults to the '89 standard, you'll need to pass --std=gnu99 or similar for it to work)
It also seems to increase executable size... or maybe that's just passing --std=c99. I had a 19 KiB file go up to about 40 when I tried using restrict on my malloc()ated pointers (of which, I had three).
Re: The obvious thing I should've learned 5 years ago
Posted: Mon Feb 01, 2010 2:45 am
by Solar
earlz wrote:I think the reason most people don't know about restrict is that it wasn't (still isn't?) included in the C++ standard...
It's high time they get that C++ standard through the door. Some things C99 introduced are sorely lacking from the C++ standard. But lo, what a beast they have to standarize, compared to the very compact C99 standard.
I openly admit that there are several corners in the C/C++ standard I know very little about. Basically, I know they exist, but not much more.
I know pretty well what 'mutable' is for, but haven't used it more than twice. I know 'explicit' exists, and remember some of the details, but would have to look it up before using it with confidence. C99 variable length arrays... I know they exist, but no more.
Nothing of that really bothers me. I almost never come across these constructs, and looking them up is a matter of seconds.
What really
does bother me is that I never got beyond the beginner's phase with regards to C++ templates / STL. I know enough to get the work done, a functor isn't an unknown beast to me, but I know that I don't know the better half of the STL half as well as I should. (Thank you, Bilbo Baggins!
) I have to look up the details of ptr_fun() every time I come across it, and stuff like compose1( negate< double >, ptr_fun( fabs ) ); leaves me scratching my head and digging through references... at least I know what to look for, and eventually figure it out, and am usually the one my co-workers ask for help when
they come across one of those, but I still feel that's my blind spot.
Too bad I don't get much experience in that regard either. Office code is far too dumb to use constructs like that, and my hobby project is C, not C++...
Re: The obvious thing I should've learned 5 years ago
Posted: Tue Feb 02, 2010 12:13 am
by Colonel Kernel
A lot of the stuff in <functional> is a hack to overcome the lack of lambda expressions. Hopefully the addition of lambdas in C++0x will make such features more accessible to everyone.
What scares me in C++0x is all the new stuff about rvalue versus lvalue references, "move constructors", "move assignment operators", etc... It seems to me like we need to tell the compiler way too much information for the sake of optimization.
Re: The obvious thing I should've learned 5 years ago
Posted: Tue Feb 02, 2010 2:44 am
by qw
Well, "register" was added for the sake of optimization from the very beginning. I have mixed feelings about this. You could add a hundred keywords to a language to tell the compiler how to optimize, but they don't contribute to the algorithm at all.
(I never use "register". I do use "const" and "volatile" however.)
Re: The obvious thing I should've learned 5 years ago
Posted: Tue Feb 02, 2010 5:24 am
by midir
earlz wrote:So I'm a self-taught C programmer.
[...]
Been programming C for over 5 years now and I'm just NOW figuring out that there is a `continue` keyword!?
Same here. It was a jubilant moment when I discovered it. Actually I discovered it in PHP first, and thought "What a great new idea!", and later discovered that C had had it all along too, for decades.
It's a really handy way to "filter" a loop without using (possibly several) nested ifs, so then you can do something complex in the loop at a lesser level of indenting.
Re: The obvious thing I should've learned 5 years ago
Posted: Tue Feb 02, 2010 5:41 am
by Solar
You "continue" guys hopefully remember to comment its usage well in your code. The ladder of evil: continue, break, goto.
Re: The obvious thing I should've learned 5 years ago
Posted: Tue Feb 02, 2010 6:20 am
by Combuster
The ladder of evil: continue, break, goto.
I'd put break above continue or goto. Especially in switch statements, you can't really get away without them. You can do without continue with little second thought. And goto, well...
Re: The obvious thing I should've learned 5 years ago
Posted: Tue Feb 02, 2010 6:24 am
by Solar
Using break in switch statements is excused. As for while loops, on the other hand...
Re: The obvious thing I should've learned 5 years ago
Posted: Tue Feb 02, 2010 8:08 am
by qw
Combuster wrote:And people don't use it because GCC does not accept restrict by default. (it defaults to the '89 standard, you'll need to pass --std=gnu99 or similar for it to work)
GCC does support the non-standard "__restrict__" since (I think) version 2.95.
Re: The obvious thing I should've learned 5 years ago
Posted: Tue Feb 02, 2010 8:27 am
by Solar
...but using -std=c99 is the way to go.
Re: The obvious thing I should've learned 5 years ago
Posted: Thu Mar 04, 2010 7:05 pm
by Synon
Solar wrote:Using break in switch statements is excused. As for while loops, on the other hand...
Depends where it is.
This is a bad use:
Code: Select all
while (true) {
blahBlahBlah();
if (condition)
break;
}
and so is this (something like this actually appeared in Beej's Guide to Network Programming) (IMO):
Code: Select all
while (condition) {
if (this)
continue;
if (that)
continue;
if (the_other)
continue;
break;
}
It's clear what it's doing but it's still a little ugly.
Would a valid use of break be to neaten up the while statement's condition:
Code: Select all
while (true) {
/* ... */
if (condition_A_which_takes_up_a_lot_of_space ||
(condition_B_which_takes_up_a_lot_of_space_too &&
condition_C_which_takes_up_even_more_space_than_A_and_B))
break;
}
?
IMO, yes. It's still ugly, but to put that in the while loop's clause would be uglier. And I have had to do that once... it was a be-all, end-all line input function. I don't have it any more because the hard disk on the computer I wrote it on is dead. Basically it was to automate doing this:
Code: Select all
printf("What option do you want to pick? [A/B]: ");
fgets(buf, bufsz, stdin);
and it evolved into
options would be an instance of struct gi_opts which said
* What stream to get the input from
* What options to display (A, B, C, Y, N or anything you wanted)
* What to use to divide the options (e.g. "/" or "|") which I removed (unnecessary)
* What to use to surround the options (e.g. "[" would be matched with "]", etc.) which I also removed for the same reason as above
* Which option was the default (-1 for none)
* What to do on invalid input (could be GI_OPTS_EXIT, GI_OPTS_REITER and/or GI_OPTS_PROMPT; the first two being mutually exclusive)
* Max amount of times to reiterate on invalid input (if GI_OPTS_REITER was chosen)
* A prompt to display
Anyway I had to do that in the while loop for the __get_input(char* buf, FILE* stream) function.
Re: The obvious thing I should've learned 5 years ago
Posted: Thu Mar 11, 2010 7:24 am
by AndrewAPrice
If now even break and continue are considered bad since they break execution flow, what are your feelings about a 'return' that is not part of the last statement in a function?
Sometimes it may not be so simple to avoid without making it messy, such as in this example:
Code: Select all
while(condition1)
{
if(condition2)
{
// heavy logic
if(condition3)
break;
// heavy logic
if(condition4)
break;
// heavy logic
}
// heavy logic
}
vs
Code: Select all
bool done = false;
while(!done)
{
if(condition1)
{
// heavy logic
if(condition3)
done = true;
else
{
// heavy logic
if(condition4)
done = true;
else
// heavy logic
}
}
if(!done)
{
// heavy logic
}
done |= condition1;
}
Re: The obvious thing I should've learned 5 years ago
Posted: Fri Mar 12, 2010 6:25 pm
by JamesM
Personally I use "early-exit" operators as much as possible in order to reduce the amount of nesting needed and therefore make code easier to read. That means break, continue, return.
They don't impact performance and it's blatantly obvious what the intention is. If it improves my code's readability, it's worth it. YMMV.
Re: The obvious thing I should've learned 5 years ago
Posted: Sat Mar 13, 2010 11:58 am
by earlz
JamesM wrote:Personally I use "early-exit" operators as much as possible in order to reduce the amount of nesting needed and therefore make code easier to read. That means break, continue, return.
They don't impact performance and it's blatantly obvious what the intention is. If it improves my code's readability, it's worth it. YMMV.
Yup, I believe Linus or some famous coder put it something like "Using break and continue is bad cause it's basically a disguised goto. But if you have over 3 levels of indentation, your screwed anyway"