Implementation of std::min [duplicate] - c++

This question already has answers here:
Correct implementation of min
(2 answers)
Closed 9 years ago.
The implementation of std::min on cppreference and in the original stl looks like this:
return (b < a) ? b : a;
But I think this is slightly more readable:
return (a < b) ? a : b;
Which makes me wonder: are both implementations equivalent? Is there a particular reason why it is implemented like it is?

The two different implementations would determine whether you choose the first or the second object as minimum if they are equal, which may make a difference for objects, if not for primitive types.
This, coupled with implementation of some other algorithms could have a larger impact. For example, if a sort algorithm uses min(a[i], a[j]) where i < j and a[i] and a[j] have the same value, the first implementation would result in no swap between the elements while the second does, making the sort unstable.
Note: As BoBTFish mentioned, the C++11 standard guarantees that both min and max return the left most minimum:
25.4.7:
3 Remarks: Returns the first argument when the arguments are equivalent
6 Remarks: Returns a copy of the leftmost argument when several arguments are equivalent to the smallest

The implementations are not the same. What will happen in either implementation if a and b are equal? One will return a reference to a one will return a reference to b. The values of course are identical. But consider a struct in which the compare function only cared about one value, but some other values were different. This could have dramatic implications on sorting functions attempting to guarantee a stable sort.
Ultimately it's a style choice, in the event of equality should we return the first or second parameter? However, now that this style choice has been made, that it remains the same is very important, this is why things like standards definitions exist!
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
Search for "25.4.7" regarding maximum and minimum.

-- INCORRECT ANSWER -- SEE COMMENTS -- bb
FWIW, it hasn't been my observation that STL was written to be especially easy to read, necessarily, but it's beautifully simple; in this case, the only other possible way to get the same result would be
return (a <= b) ? a : b;
which would be one more character, and, IMHO, actually not as easy to read. Additionally, see #Shahbaz 's commentary above on sort stability--operations like min have a well-defined behavior for inclusivity and exclusivity.
TL;DR because "Less than" is not the same as "Less than or equal to"
See comments below--this answer would be correct as a macro in C but actually is incorrect in C++ for reasons explained in the comments below. I'm marking this as incorrect but leaving it up because the comments are useful and important to understand. I apologize if I confused the issue for anyone.

Related

Double increment on an integer variable, does it work as intended? [duplicate]

This question already has answers here:
Multiple preincrement operations on a variable in C++(C ?)
(2 answers)
Closed 6 years ago.
I have some code with lines which increment a counter.
++ count;
Sometimes I have an if condition which means I should increment count by 2.
count += 2;
Does "double increment'ing" work in the same way?
++ ++ count;
It would be helpful to know if both C and C++ compilers interpret this the same way.
As this is clearly syntactically correct, the question that remains is: "Is this UB because of unsequenced writes?"
It is not (in C++11 and later) because
5) The side effect of the built-in pre-increment and pre-decrement operators is sequenced before its value computation (implicit rule due to definition as compound assignment)
(From here)
So the code is fine as of C++11.
However, the sequencing rules were different before that, and pre-C++11, the code actually has UB.
In C, that code does not even compile.
The fact that the behavior is different between C and C++ and even between different C++ standards and that this question arises in the first place is a hint that the simple count += 2; is the safer and more readable version. You should prefer it over the "cute and clever" ++ ++count;.
There are two methods. One that obviously works, one where you have to ask a question on StackOverflow. There are comments saying "in C++ 11 or later"... How sure are you that your C++ code runs with C++ 11 and not something older? Even if you use extensions that were not part of an earlier language, your language could be C++0x with some extensions.
Clearly you shouldn't care whether the second method works or not, but use the one that obviously works.

What are the historical reasons C languages have pre-increments and post-increments?

(Note: I am not asking about the definitions of pre-increment vs. post-increment, or how they are used in C/C++. Therefore, I do not think this is a duplicate question.)
Developers of C (Dennis Ritchie et al) created increment and decrement operators for very good reasons. What I don't understand is why they decided to create the distinction of pre- vs post- increments/decrements?
My sense is that these operators were far more useful when C was being developed than today. Most C/C++ programmers use one or the other, and programmers from other languages find the distinction today bizarre and confusing (NB: this is based solely on anecdotal evidence).
Why did they decide to do this, and what has changed in computation that this distinction isn't so useful today?
For the record, the difference between the two can be seen in C++ code:
int x = 3;
cout << "x = 3; x++ == " << x++ << endl;
cout << "++x == " << ++x << endl;
cout << "x-- == " << x-- << endl;
cout << "--x == " << --x << endl;
will give as an output
x++ == 3
++x == 5
x-- == 5
--x == 3
Incrementing and decrementing by 1 were widely supported in hardware at the time: a single opcode, and fast. This because "incrementing by 1" and "decrementing by 1" were a very common operation in code (true to this day).
The post- and predecrement forms only affected the place where this opcode got inserted in the generated machine code. Conceptually, this mimics "increase/decrease before or after using the result". In a single statement
i++;
the 'before/after' concept is not used (and so it does the same as ++i;), but in
printf ("%d", ++i);
it is. That distinction is as important nowadays as it was when the language C was designed (this particular idiom was copied from its precursor named "B").
From The Development of the C Language
This feature [PDP-7's "`auto-increment' memory cells"] probably suggested such operators to Thompson [Ken Thompson, who designed "B", the precursor of C]; the generalization to make them both prefix and postfix was his own. Indeed, the auto-increment cells were not used directly in implementation of the operators, and a stronger motivation for the innovation was probably his observation that the translation of ++x was smaller than that of x=x+1.
Thanks to #dyp for mentioning this document.
When you count down from n it is very important whether is pre-decrement or post-decrement
#include <stdio.h>
void foopre(int n) {
printf("pre");
while (--n) printf(" %d", n);
puts("");
}
void foopost(int n) {
printf("post");
while (n--) printf(" %d", n);
puts("");
}
int main(void) {
foopre(5);
foopost(5);
return 0;
}
See the code running at ideone.
To get an answer that goes beyond speculation, most probably you have to ask Dennis Ritchie et al personally.
Adding to the answer already given, I'd like to add two possible reasons I came up with:
lazyness / conserving space:
you might be able to save a few keystrokes / bytes in the input file using the appropriate version in constructs like while(--i) vs. while(i--). (take a look at pmg s answer to see, why both make a difference, if you didn't see it in the first run)
esthetics
For reasons of symmetry having just one version either pre- or postincrement / decrement might feel like missing something.
EDIT: added sparing a few bytes in the input file in the speculation section providing, now providing a pretty nice "historic" reason as well.
Anyways the main point in putting together the list was giving examples of possible explanations not being too historic, but still holding today.
Of course I am not sure, but I think asking for a "historic" reason other than personal taste is starting from a presumtion not neccesarily true.
For C
Let's look at Kernighan & Ritchie original justification (original K&R page 42 and 43):
The unusual aspects is that ++ and -- may be used either as prefix or
as postfix. (...) In the context where no value is wanted (..) choose
prefix or postfix according to taste. But htere are situations where
one or the other is specifically called for.
The text continues with some examples that use increments within index, with the explicit goal of writing "more compact" code. So the reason behind these operators is convenience of more compact code.
The three examples given (squeeze(), getline() and strcat() ) use only postfix within expressions using indexing. The authors compare the code with a longer version that doesn't use embedded increments. This confirms that focus is on compactness.
K&R highlight on page 102, the use of these operators in combination with pointer dereferencing (eg *--p and *p--). No further example is given, but again, they make clear that the benefit is compactness.
For C++
Bjarne Stroustrup wanted to have C compatibility, so C++ inherited prefix and postfix increment and decrement.
But there's more on it: in his book "The design and evolution of C++", Stroustrup explains that initially, he planned have only one overload for both, postfix and prefix, in user defined classes:
Several people, notably Brian Kernighan, pointed out that this
restriction was unnatural from a C perspective and prevented users
from defining a class that could be used as replacement for an
ordinary pointer.
Which caused him to find the current signature difference to differentiate prefix and postfix.
By the way, without these operators C++ would not be C++ but C_plus_1 ;-)
Consider the following loop:
for(uint i=5; i-- > 0;)
{
//do something with i,
// e.g. call a function that _requires_ an unsigned parameter.
}
You can't replicate this loop with a pre-decrement operation without moving the decrement operation outside of the for(...) construct, and it's just better to have your initialization, interation and check all in one place.
A much larger issue is this: one can over-load the increment operators (all 4) for a class. But then the operators are critically different: the post operators usually result in a temporary copy of the class instance being made, where as the pre-operators do not. That is a huge difference in semantics.
The PDP-11 had a single instruction that corresponded to *p++, and another for *--p (or possibly the other way round).

Why does the C++ standard not deprecate the increment/decrement operators? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I think the following code is evil, but it can be compiled without any warning.
int f(int n)
{
return n + 1;
}
int n = 0;
n = f(n++) + f(++n);
I just wonder why the Holy Standard doesn't deprecate such operators?
I guess there might be two reasons:
One might be for backward compatibility;
Another might be for that under some cases these operators are very useful.
If the latter is true, could you give me some examples? Thanks.
It's more than evil, it's Undefined Behaviour™. Which is why all sane people ban such uses.
Backwards compatibility is surely half the problem- increment and decrement are used everywhere. They're also useful for iterators and stuff.
The bottom line is, C++ has never, ever stopped you from shooting yourself in the foot. This is just one example. C++ does not ban things that can be good just because they can be bad. Not abusing them is your problem.
To remove these ++ and -- operators from C and/or C++ would certainly break A LOT of code - in fact I suspect, if you remove those two operators, just about every single existing source file will stop compiling.
They are very useful when used correctly - as long as you don't use it on both sides of the same variable, you'll be fine.
This code won't compile, but adding parenthesis to make it (++n)++ does compile correctly - but g++ gives a warning "operation on ‘n’ may be undefined".
And if we remove the ++ and -- operator, how do you expect to write a common for-lopp:
for(int i = 0; i < 100; i++)
like this:
for(int i = 0; i < 100; i = i + 1)
or
for(int i = 0; i < 100; i += 1)
Banning everything that can be misused in C and C++ would pretty much reduce the language to nothing - and certainly either make the language completely useless or at least prevent a lot of valid uses. It'd be like banning knifes, because people CAN use them (and indeed have used them) for bad things. But if you want to cut bread, meat or vegetables, they do make darn handy tools for that purpose.
I just wonder why the Holy Standard doesn't deprecate such operators?
Because this is perfectly valid code, but it invokes unspecified behavior, since the order of evaluation of operands in a C expression isn't specified. The only problem in the code was created by the programmer, who has written code that relies on unspecified behavior. It is not the C standard's task to educate programmers about the language.
(This is not undefined behavior. See C11 6.5.2.2. There is a sequence point between the evaluations of the function designator and actual arguments in a function call and the actual call. Had it not been for the sequence point after each function parameter evaluation, it would have been undefined behavior, because you can't modify the same variable twice in an operation without a sequence point in between.)
One might be for backward compatibility;
No. C has always had unspecified order of evaluation of operands. This code works the same from pre-standard K&R code all the way to C11.
Another might be for that under some cases these operators are very useful.
No, the code you posted is not useful in any kind of scenario. It is obfuscated and can be written in better ways to achieve the very same functionality and identical machine code, in a safer, more readable way. For example:
n++;
n = f(n) + f(n);
n++;

Late return value in C++

Today I did a funny mistake in my C++ code. I have a function with two arguments of type std::vector<int>::iterator& (i and j). Iterators should point to same vector. Function should return sum of two numbers in the vector, and move both iterators forward to j+1th position of vector:
int exp_func_add::evaluate(vector<int>::iterator& i, vector<int>::iterator& j) {
int result = *i + *j;
++j;
i = j;
return result;
}
First I wrote this code:
int exp_func_add::evaluate(vector<int>::iterator& i, vector<int>::iterator& j) {
++j;
i = j;
return (*i+*j); // <====== Oops !
}
We know that return statement returns control to caller. My question is why C++ standard does not define a late value return semantics? Let's call it late_return keyword:
int exp_func_add::evaluate(vector<int>::iterator& i, vector<int>::iterator& j) {
late_return *i+*j; // Hold return value but don't go back
// to the caller until leaving scope
++j;
i = j;
}
This question may get hundreds of downvotes (not constructive, blah blah). Though I would like to ask some questions:
Is there a way to simulate this behavior using macros or any other tricks?
Do this deserve an implementation or to be considered as a feature in next c++ standard?
Are there programming languages implementing similar feature?
Is there a way to simulate this behavior using macros or any other tricks?
Not really, though your first code sample is fairly idiomatic C or C++ code.The "assign a value to "result", and then have 'return result' as the last statement of the function is avery common pattern.
Do this deserve an implementation or to be considered as a feature in next c++ standard?
No, because it adds complexity without any clear benefit over the existing idiom. It'd add a whole bunch of edge cases to the language, too. Functions can have more than one return statement, so how so you handle multiple late_return statements? First one wins? Last one wins? Throw an exception? What about a code path that includes late_return and return?
Are there programming languages implementing similar feature?
The closest thing I can think of is constraints languages or logic languages like Prolog, where the "result" is produced as soon as all of the data necessary to produce it has been provided.
Is there a way to simulate this behavior using macros or any other tricks?
Yes, and you said it yourself: define a variable called ret and return it at the end. That's only one line more and it's a lot more clear what is going on when you get to the end of the function.
If I understand the question correctly you are essentially looking to do something like this:
return *i + *(++j, i=j, j-1);
The problem with this is that i may already be changed by the time we get to it. It will not necessarily (won't?) evaluate this statement left-to-right.
As other posters have mentioned this really doesn't provide any added benefit to the language, except maybe to save a line or two of code. That being said, it sounds to me like you want something like a reverse comma operator.
It doesn't exist, but the idea has been brought up here and here.
All in all, I think it adds significant complexity in a situation where it really is not needed. I don't see this as a bad question because it is always good to try and better understand how/why things work. I just don't think this particular use case warrants it.

Optimized code: is ++p faster than p++? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is there a performance difference between i++ and ++i in C++?
In C++, I see people frequently use ++p in a for loop or elsewhere, where you want to increment a value, but not use the return value. I've heard this is more efficient because p++ returns the value before incrementing, and thus requires a temporary space.
But, it feels that even a very ignorant compiler will pull out that return value as dead code (as long as the increment code is inlined, and so the compiler can see that the return value wasn't necessary).
I'm trying to come up with a good example where, using some sort of iterator, iter++ will actually create the copy (even though the return value of iter++ is not used.
After all, we don't really frequently consider register allocation either when we write code with iterators.
I learned to use p++ simply because that's what the book I learned from did. Is preferring ++p when no return value is used an archaic practice, or simply part of elegant coding? And why is the language not called ++C then?
p++ is slower only when ++p doesn't do the job - i.e. when you actually use the return value. Otherwise, the compiler will optimize the code to the same thing.
People prefer using ++i instead of i++ because it describes better what you intend to do: increment i, more than increment i and return the old value. Of course, you tend to stick to old habits. If you're used to writing i++, that's ok, unless the coding standards of the company you work for mandate you use ++i.
Chapter 3 of D&E: ``I picked C++ because it was short, had nice
interpretations, and wasn't of the form "adjective C."' In C, ++ can,
depending on context, be read as "next," "successor," or "increment,"
though it is always pronounced "plus plus." The name C++ and its
runner up ++C are fertile sources for jokes and puns -- almost all of
which were known and appreciated before the name was chosen. The name
C++ was suggested by Rick Mascitti. It was first used in December of
1983 when it was edited into the final copies of [Stroustrup,1984] and
[Stroustrup,1984c].
Chapter 1 of TC++PL: ``The name C++ (pronounced
"see plus plus") was coined by Rick Mascitti in the summer of 1983.
The name signifies the evolutionary nature of the changes from C; "++"
is the C increment operator. The slightly shorter name "C+" is a
syntax error; it has also been used as the name of an unrelated
language. Connoisseurs of C semantics find C++ inferior to ++C. The
language is not called D, because it is an extension of C, and it does
not attempt to remedy problems by removing features. For yet another
interpretation of the name C++, see the appendix of [Orwell,1949].''
Sauce.
Depending on the iterator, creating a copy can be an extremely time consuming task (think about a naive, stack based iterator for a binary search tree). I suppose you realize that though, and that's not your real question :). Anyway, as far as I'm aware, the compiler is not required to optimize i++ to ++i.
As it's not required to optimize it, I would think it's better to err on the side of caution and stick with ++i.