The obvious thing I should've learned 5 years ago
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: The obvious thing I should've learned 5 years ago
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
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).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)
Re: The obvious thing I should've learned 5 years ago
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.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...
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++...
Every good solution is obvious once you've found it.
- Colonel Kernel
- Member
- Posts: 1437
- Joined: Tue Oct 17, 2006 6:06 pm
- Location: Vancouver, BC, Canada
- Contact:
Re: The obvious thing I should've learned 5 years ago
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.
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.
Top three reasons why my OS project died:
- Too much overtime at work
- Got married
- My brain got stuck in an infinite loop while trying to design the memory manager
Re: The obvious thing I should've learned 5 years ago
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.)
(I never use "register". I do use "const" and "volatile" however.)
Re: The obvious thing I should've learned 5 years ago
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.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!?
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
You "continue" guys hopefully remember to comment its usage well in your code. The ladder of evil: continue, break, goto.
Every good solution is obvious once you've found it.
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: The obvious thing I should've learned 5 years ago
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...The ladder of evil: continue, break, goto.
Re: The obvious thing I should've learned 5 years ago
Using break in switch statements is excused. As for while loops, on the other hand...
Every good solution is obvious once you've found it.
Re: The obvious thing I should've learned 5 years ago
GCC does support the non-standard "__restrict__" since (I think) version 2.95.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)
Re: The obvious thing I should've learned 5 years ago
...but using -std=c99 is the way to go.
Every good solution is obvious once you've found it.
Re: The obvious thing I should've learned 5 years ago
Depends where it is.Solar wrote:Using break in switch statements is excused. As for while loops, on the other hand...
This is a bad use:
Code: Select all
while (true) {
blahBlahBlah();
if (condition)
break;
}
Code: Select all
while (condition) {
if (this)
continue;
if (that)
continue;
if (the_other)
continue;
break;
}
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);
Code: Select all
get_input(buf, &options);
* 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.
- AndrewAPrice
- Member
- Posts: 2299
- Joined: Mon Jun 05, 2006 11:00 pm
- Location: USA (and Australia)
Re: The obvious thing I should've learned 5 years ago
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:
vs
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
}
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;
}
My OS is Perception.
Re: The obvious thing I should've learned 5 years ago
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.
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
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"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.