I have the following code, that I wrote to test a part of a larger program :
#include <fstream>
#include <random>
#include <iostream>
using namespace std ;
int main()
{
mt19937_64 Generator(12187) ;
mt19937_64 Generator2(12187) ;
uniform_int_distribution<int> D1(1,6) ;
cout << D1(Generator) << " " ;
cout << D1(Generator) << " " << D1(Generator) << endl ;
cout << D1(Generator2) << " " << D1(Generator2) << " " << D1(Generator2) << endl ;
ofstream g1("g1.dat") ;
g1 << Generator ;
g1.close() ;
ofstream g2("g2.dat") ;
g2 << Generator2 ;
g2.close() ;
}
The two generators are seeded with the same value, and therefore I expected the second row in the output to be identical to the first one. Instead, the output is
1 1 3
1 3 1
The state of the two generators as printed in the *.dat files is the same. I was wondering if there might be some hidden multi-threading in the random number generation causing the order mismatch.
I compiled with g++ version 5.3.0, on Linux, with the flag -std=c++11.
Thanks in advance for your help.
x << y is syntactic sugar for a function call to operator<<(x, y).
You will remember that the c++ standard places no restriction on the order of evaluation of the arguments of a function call.
So the compiler is free to emit code that computes x first or y first.
From the standard: §5 note 2:
Operators can be overloaded, that is, given meaning when applied to expressions of class type (Clause
9) or enumeration type (7.2). Uses of overloaded operators are transformed into function calls as described
in 13.5. Overloaded operators obey the rules for syntax specified in Clause 5, but the requirements of
operand type, value category, and evaluation order are replaced by the rules for function call.
That's because the order of evaluation of this line
cout << D1(Generator2) << " " << D1(Generator2) << " " << D1(Generator2) << endl ;
is not what you think.
You can test it with this:
int f() {
static int i = 0;
return i++;
}
int main() {
cout << f() << " " << f() << " " << f() << endl ;
return 0;
}
Output: 2 1 0
The order is not specified by the C++ standard, so the order could be different on other compilers, please see Richard Hodges' answer.
A slight change to the program reveals what happens:
#include <fstream>
#include <random>
#include <iostream>
using namespace std ;
int main()
{
mt19937_64 Generator(12187) ;
mt19937_64 Generator2(12187) ;
uniform_int_distribution<int> D1(1,100) ;
cout << D1(Generator) << " " ;
cout << D1(Generator) << " " ;
cout << D1(Generator) << endl ;
cout << D1(Generator2) << " " << D1(Generator2) << " " << D1(Generator2) << endl ;
}
Output:
4 48 12
12 48 4
So your Generators produce equal results - but the order the arguments of your cout-line are calculated in different order.
Try it online:
http://ideone.com/rsoqDe
These lines
cout << D1(Generator) << " " ;
cout << D1(Generator) << " "
<< D1(Generator) << endl ;
cout << D1(Generator2) << " "
<< D1(Generator2) << " "
<< D1(Generator2) << endl ;
because D1() returns an int, for which ostream::operator<<() has an overload, are effectively calling (excluding endl)
cout.operator<<(D1(Generator));
cout.operator<<(D1(Generator))
.operator<<(D1(Generator));
cout.operator<<(D1(Generator2))
.operator<<(D1(Generator2))
.operator<<(D1(Generator2));
Now, the standard has this to say,
§ 5.2.2 [4]
When a function is called, each parameter shall
be initialized with its corresponding argument.
[ Note: Such initializations are indeterminately sequenced with respect to each other — end note ]
If the function is a non-static
member function, the this parameter of the function shall be
initialized with a pointer to the object of the call
So let's break down the preceding expression
cout.operator<<(a()) // #1
.operator<<(b()) // #2
.operator<<(c()); // #3
To illustrate the construction of the this pointer, these are conceptually equivalent to (omitting ostream:: for brevity):
operator<<( // #1
&operator<<( // #2
&operator<<( // #3
&cout,
a()
), // end #3
b()
), // end #2
c()
); // end #1
Now let's look at the top-level call. Which do we evaluate first, #2, or c()? Since, as emphasized in the quote, the order is indeterminate, then we don't know—and this is true recursively: even if we evaluated #2, we would still face the question of whether to evaluate its internal #3 or b().
So that hopefully explains what's going on here more clearly.
Related
I have troubles with homework. The task is to implement files included in main.cpp so the program will work. main.cpp is the file we get from our teacher - we can't make any changes in it. At the end of it there is written a desired output. (note: there shouldn't be any overloaded operators).
This is what I did so far: https://wandbox.org/permlink/ffzkdaVoYK8Qovic
I can't get it to work properly. I don't know what I am doing wrong:
There must be some error with Differential. Teacher said that we don't need to use clone() method in it - so I didn't - but when I do, in constructor instead of setF, I'm getting segmentation fault. The same happens in function in(), when I'm trying to return the result according to the formula - and I don't get why it happens.
I get -5 instead of 5 (see output below main.cpp). Some math error? I can't spot it.
I have a feeling my class hierarchy is really bad. What should it be instead? (Guessing from the lecture there should be virtual inheritance, multiple inheritance and a solution to diamond problem - but well, that's just my guess.) I'm also getting some warnings when compiling and I didn't fix them because I think I just did the hierarchy wrong and if I fix it the problem will be gone.
In general, what can I fix in my code to make it better?
Here is main.cpp (it's also in the link to my solution):
#include "Fun.h"
#include "Elementary.h"
#include "Compound.h"
#include "Differential.h"
#include <iostream>
int main()
{
std::cout << "=====-===== 2 =====-=====" << std::endl;
Fun * lfun = Linear::create()->a(2.)->b(-1.); // This is ax + b = 2x-1
Fun * sfun = new Sinus;
std::cout << lfun->value(0.1) << " " << lfun->value(0) << std::endl;
std::cout << sfun->value(0.1) << " " << sfun->value(0) << std::endl;
std::cout << "=====-===== 2 =====-=====" << std::endl;
Fun * qbase = Quadratic::create()->a(1)->b(0.)->c(-4.);
Fun * qfun = qbase->clone(); // Cloning
std::cout << qbase->value(0.1) << " " << qbase->value(0) << std::endl;
std::cout << qfun->value(0.1) << " " << qfun->value(0) << std::endl;
delete qbase;
std::cout << qfun->value(0.1) << " " << qfun->value(0) << std::endl;
std::cout << "=====-===== 2 =====-=====" << std::endl;
Differential diff(0.01); // 0.01 is h
std::cout << "value of differential from lfun in 1.0 = " << diff.from(lfun)->in(1) << std::endl;
std::cout << "value of differential from qfun in 2.1 = " << diff.from(qfun)->in(2.1) << std::endl;
std::cout << "value of differential from sfun in 0.12 = " << diff.from(sfun)->in(0.12) << std::endl;
std::cout << "=====-===== 1 =====-=====" << std::endl;
Fun* comp = new Compound(lfun, qfun);
std::cout << "value of compound function " << comp->value(2) << std::endl; // Result from: qfun( lfun( 2 ) )
delete lfun;
delete qfun;
delete sfun;
std::cout << "=====-===== 1 =====-=====" << std::endl;
std::cout << "Compound func still works: " << comp->value(2) << std::endl;
delete comp;
}
/*********************************** OUTPUT ************************************
--------------------------------------------------------------------------------
=====-===== 2 =====-=====
-0.8 -1
0.0998334 0
=====-===== 2 =====-=====
-3.99 -4
-3.99 -4
-3.99 -4
=====-===== 2 =====-=====
value of differential from lfun in 1.0 = 2
value of differential from qfun in 2.1 = 4.2
value of differential from sfun in 0.12 = 0.992792
=====-===== 1 =====-=====
value of compound function 5
=====-===== 1 =====-=====
Compound func still works: 5
--------------------------------------------------------------------------------
*******************************************************************************/
AFAIK it is illegal to take the address of an rvalue because the address-of operator & takes an lvalue and returns the address of the object's called on address.
Here is an example I've tried to understand but find it a bit confusing:
#include <deque>
#include <iostream>
int main() {
using std::cout;
using std::endl;
std::deque<int> di{ 1, 1, 2, 3, 5, 8, 13 };
std::deque<int>::iterator it = di.end() - 1;
cout << *it << endl;
cout << &it-- << endl; // is it UB?
cout << *it << endl;
cout << &it-- << endl;
cout << *it << endl;
cout << &it-- << endl;
cout << *it << endl << endl;
cout << &--it << endl; // ok
cout << *it << endl; // ok
cout << &--it << endl; // ok
cout << *it << endl; // ok
std::cout << std::endl << "done!" << std::endl;
}
In the lines where I've used the pre-decrement operator it is OK because this operator and & have the same precedence level and are evaluated from right-to-left (RL) thus -- evaluates first and it returns an lvalue (takes also lvalue). then & is evaluated so & on an lvalue is OK.
The problem above in the post-decrement operator which takes an lvalue and returns an rvalue and has higher precedence over &. So in these expressions I am calling & on rvalue which is normally not allowed. But why the code compile and gives different results (addresses)??
When compiled on Wandbox with flag -pedantic it doesn't compile:
prog.cc:25:17: error: taking address of rvalue [-fpermissive]
25 | cout << &offEnd-- << endl; // -- has higher precedence than & thus this expression decrements offEnd and returns a copy of original of offEnd then print the address of this original object (before decrementing it)
Also on MSVC++14 with /Wall.
So is it undefined behavior in my code?
so why C++ allowed calling address of operator & on rvalue while the standard disallows it?
Finally I want to know where theses different addresses come from in such expression: std::cout << &it-- << std::endl;? But the values of de-referencing are correct!
I have a C++ learning demo here:
char c = 'M';
short s = 10;
long l = 1002;
char * cptr = &c;
short * sptr = &s;
long * lptr = &l;
cout << "cptr:\t" << static_cast<void*>(cptr) << '\n';
cout << "cptr++:\t" << static_cast<void*>(++cptr) << '\n';
cout << "sptr:\t" << sptr << '\n';
cout << "sptr++:\t" << ++sptr << '\n';
cout << "lptr:\t" << lptr << '\n';
cout << "lptr++:\t" << ++lptr << '\n';
cout << c << '\t' << static_cast<void*>(cptr) << '\t' << static_cast<void*>(++cptr) << '\n';
cout << s << '\t' << sptr << '\t' << ++sptr << '\n';
cout<< l << '\t' << lptr << '\t'<< ++lptr << '\n';
The compiler warnings:
Can anyone explain this to me? How to fix it?
Since C++17 the code is correct.
Prior to C++17 the evaluation of operands of a << chain was unsequenced, so the code caused undefined behaviour.
The compiler warning suggests you are not compiling in C++17 mode. To fix it you could either:
Compile in C++17 mode, or
Separate the << chain into multiple cout << statements where there is not x and ++x within the same statement.
Note: As of now, all versions of g++ seem to be bugged and not implement these sequencing requirements correctly, see this thread for some more examples. The warnings can be seen as indicating the compiler bug; they are not just bogus warnings.
You re having undefined behavior in lines 18, 19, 20. Cause of the result of executing the line will be different depending on whether ptr or ++ptr is evaluated first.
According to C++ Standard Draft Paper N4762 (2018-07-07) on page 68 in section § 6.8.1/10
( or [intro.execution]/10 on eel.is website here )
Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced.
For statement
cout << c << '\t' << static_cast<void*>(cptr) << '\t' << static_cast<void*>(++cptr) << '\n';
that means c++ compiler can not guarantee that static_cast<void*>(cptr) will be evaluated before ++cptr on the right because they are all operands on the same statement.
So you can force their sequential order of execution simply by ordering them in ordered and separated statements.
For example :
cout << c << '\t' << static_cast<void*>(cptr) << '\t'; cout << static_cast<void*>(++cptr) << '\n';
[ compiler explorer ]
Update
As M.M's answer states that c++17 now guarantees operand evaluation sequence of <<
It turns out that GCC 8.1 doesn't warn, even with std=c++11, unless with -Wall and always warns with -Wall
While clang 6.0 warns "no matter what".
[ compiler explorer ]
So, as well as -std=c++17, you must also provide option -Wno-unsequenced to suppress it :
if you are on clang 6.0
if you are on gcc 8.1 with -Wall
sorry for asking you a stupid question, but I just can't figure out why I keep on getting this output.
So here is my code:
#include <cstdio>
#include <iostream>
using namespace std;
unsigned n = 4242;
int getRemainderOf(int m, int n, int& quotient);
static int l = 0;
int main()
{
int quotient; // the value of which should be changed after calling the func.
for(int i=-1; i<=1; ++i)
{
for(int j=-1; j<=1; ++j)
{
if( i && j )
{
cout << "("<< i*3 << "," << j*7 << ") " <<( getRemainderOf(i*3, 7*j, quotient) ) << " " << quotient <<endl;
cout << "("<< i*7 << "," << j*3 << ") " << getRemainderOf(i*7, 3*j, quotient) << " "; cout << quotient <<endl;
}
}
}
return 0;
}
int getRemainderOf(int m, int n, int& quotient)
{
++l;
cout << l <<endl;
quotient = m / n;
cout << " quotient " << quotient <<endl;
return m % n;
}
so what I expected to see in the first line of my output was the remainder and then the quotient that I get after calling the function getRemainderOf(). But instead when I cout the value of quotient like that I see that the value of quotient is a garbage value. So the value of the variable is not changed even though I've passed it to the function by using reference.
The funny thing is that if I cout the remainder (got by calling the function) and the quotient separately I will get it right.
I see that the problem might be in calling the function as a argument of the operator << function but I don't get it why the value of the quotient isn't changed since I call the function before I output it. This operator's associativity is left-to-right so what's wrong?
So could you please tell me what is the reason of this output.
What you've just found is a classic example of one of the quirks of C++. Your program can actually be decomposed into this simple example:
int i = 10;
f(i, ++i);
The compiler has the choice of function argument evaluation from left-to-right, but this is not guaranteed. Here's some standard text:
5.2/4 Postfix Epressions [expr.post]
When a function is called, each parameter shall be initialized with its corresponding argument. [Note: Such initializations are indeterminatly sequenced with respect to each other (1.9) - end note]
Because they are indeterminatly sequenced, the compiler has the freedom of evaluating ++i before the first argument and initializing it with the corresponding function parameter, and then evaluating i and initializing it with its respective parameter next.
The reason function call argument evaluation ambiguity is applicable here is because operator<<() is a function but it's just being called with the operator syntax. For example, this is what your code looks like if we use the operator-id syntax:
std::operator<<(std::operator<<(std::operator<<(std::cout, "(").operator<<(i*3), ",").operator<<(j*7), ")").operator<<(getRemainderOf(i*3, 7*j, quotient)).operator<<(quotient);
These are just chains of function calls with arguments and they obey the same rule as the one above.
The solution is to sequence the act of modifying the object and using it in the operator<<() call. You already achieved this with partitioning the operator<<() call into two statements with the semicolon ;, so the function is guaranteed to be called before quotient is printed.
The order of evaluation of function arguments is unspecified.
In these statements
cout << "("<< i*3 << "," << j*7 << ") " <<( getRemainderOf(i*3, 7*j, quotient) ) << " " << quotient <<endl;
cout << "("<< i*7 << "," << j*3 << ") " << getRemainderOf(i*7, 3*j, quotient) << " "; cout << quotient <<endl;
there are called overloaded operators << that are in fact functions. You have to split each statement in two statements. For example
cout << "("<< i*3 << "," << j*7 << ") " <<( getRemainderOf(i*3, 7*j, quotient) ) ;
cout << " " << quotient <<endl;
I want to print the first 2 values where the next is doubled from the current value.
#include <iostream>
#include <deque>
#include <algorithm>
using namespace std;
bool doubled (int x, int y) { return x*2 == y; }
int main()
{
deque<int> di;
deque<int>::iterator diiter;
for (int i=0; i<=10; i+=2) di.insert(di.end(), i);
for (diiter = di.begin(); diiter != di.end(); ++diiter)
cout << *diiter << " ";
cout << endl;
diiter = adjacent_find(di.begin(), di.end(), doubled);
if (diiter != di.end()) {
cout << "found " << *diiter << " at " << distance(di.begin(), diiter)+1
<< " and " << *(++diiter) << " at " << distance(di.begin(), diiter)+1
<< endl;
}
}
the output is
0 2 4 6 8 10
found 4 at 3 and 4 at 2
not what I expected, which should be:
0 2 4 6 8 10
found 2 at 2 and 4 at 3
What's wrong with my code? I don't understand how the second position is decremented from the first one when I actually incremented it.
Thanks for all help.
Your program is giving strange results because it does not take in to account the fact, that order of evaluation of arguments to a function(In this case operator <<) is Unspecified.
My Answer here, explains the problem in detail & should be a good read.
You need to cout them on separate statements.
cout << "found " << *diiter;
cout << " at " << distance(di.begin(), diiter)+1;
cout << " and " << *(++diiter);
cout << " at " << distance(di.begin(), diiter)+1;
cout << endl;
This works well & outputs the correct/desired output.