void sequencingOfMoveAndReinit() { // Move and reinitialization as function arguments (which are indeterminately // sequenced). Again, check that we warn for both orderings. { A a; passByValue(std::move(a), (a = A())); a.foo(); // CHECK-MESSAGES: [[@LINE-1]]:5: warning: 'a' used after it was moved // CHECK-MESSAGES: [[@LINE-3]]:17: note: move occurred here } { A a; passByValue((a = A()), std::move(a)); a.foo(); // CHECK-MESSAGES: [[@LINE-1]]:5: warning: 'a' used after it was moved // CHECK-MESSAGES: [[@LINE-3]]:28: note: move occurred here } // Common usage pattern: Move the object to a function that mutates it in some // way, then reassign the result to the object. This pattern is fine. { A a; a = MutateA(std::move(a)); a.foo(); } }
// Relative sequencing of reinitialization and use. If the two are unsequenced, // we conservatively assume that the reinitialization happens after the use, // i.e. that the object is not reinitialized at the point in time when it is // used. void sequencingOfReinitAndUse() { // Reinitialization and use in function arguments. Again, check both possible // orderings. { A a; std::move(a); passByValue(a.getInt(), (a = A())); // CHECK-MESSAGES: [[@LINE-1]]:17: warning: 'a' used after it was moved // CHECK-MESSAGES: [[@LINE-3]]:5: note: move occurred here } { A a; std::move(a); passByValue((a = A()), a.getInt()); // CHECK-MESSAGES: [[@LINE-1]]:28: warning: 'a' used after it was moved // CHECK-MESSAGES: [[@LINE-3]]:5: note: move occurred here } }
int main() { int twenty = 20; passByValue(twenty); printf("twenty is now %d\n", twenty); //It didnt change its value passByAddress(&twenty); //because this function takes a pointer we need to pass the memory address of twenty printf("twenty is now %d\n", twenty);//It changed this time!! return 0; }
//-------------------------------------------------------------- void ofApp::setup(){ for(int x=0; x < 11; x++){ circle c; c.x = ofRandom(ofGetWidth()); c.y = ofRandom(ofGetHeight()); c.width = ofMap(c.x,0,1024,0,100); c.height = c.width; circles.push_back(c); } x = 10; //rx = x; passByValue(x); cout<<x<<"is he value of x after running the function passbyvalue"<<endl; }
void sequencingOfMoveAndUse() { // This case is fine because the move only happens inside // passByRvalueReference(). At this point, a.getInt() is guaranteed to have // been evaluated. { A a; passByRvalueReference(a.getInt(), std::move(a)); } // However, if we pass by value, the move happens when the move constructor is // called to create a temporary, and this happens before the call to // passByValue(). Because the order in which arguments are evaluated isn't // defined, the move may happen before the call to a.getInt(). // // Check that we warn about a potential use-after move for both orderings of // a.getInt() and std::move(a), independent of the order in which the // arguments happen to get evaluated by the compiler. { A a; passByValue(a.getInt(), std::move(a)); // CHECK-MESSAGES: [[@LINE-1]]:17: warning: 'a' used after it was moved // CHECK-MESSAGES: [[@LINE-2]]:29: note: move occurred here // CHECK-MESSAGES: [[@LINE-3]]:17: note: the use and move are unsequenced } { A a; passByValue(std::move(a), a.getInt()); // CHECK-MESSAGES: [[@LINE-1]]:31: warning: 'a' used after it was moved // CHECK-MESSAGES: [[@LINE-2]]:17: note: move occurred here // CHECK-MESSAGES: [[@LINE-3]]:31: note: the use and move are unsequenced } // An even more convoluted example. { A a; g(g(a, std::move(a)), g(a, std::move(a))); // CHECK-MESSAGES: [[@LINE-1]]:9: warning: 'a' used after it was moved // CHECK-MESSAGES: [[@LINE-2]]:27: note: move occurred here // CHECK-MESSAGES: [[@LINE-3]]:9: note: the use and move are unsequenced // CHECK-MESSAGES: [[@LINE-4]]:29: warning: 'a' used after it was moved // CHECK-MESSAGES: [[@LINE-5]]:7: note: move occurred here // CHECK-MESSAGES: [[@LINE-6]]:29: note: the use and move are unsequenced } // This case is fine because the actual move only happens inside the call to // operator=(). a.getInt(), by necessity, is evaluated before that call. { A a; A vec[1]; vec[a.getInt()] = std::move(a); } // However, in the following case, the move happens before the assignment, and // so the order of evaluation is not guaranteed. { A a; int v[3]; v[a.getInt()] = intFromA(std::move(a)); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: 'a' used after it was moved // CHECK-MESSAGES: [[@LINE-2]]:21: note: move occurred here // CHECK-MESSAGES: [[@LINE-3]]:7: note: the use and move are unsequenced } { A a; int v[3]; v[intFromA(std::move(a))] = intFromInt(a.i); // CHECK-MESSAGES: [[@LINE-1]]:44: warning: 'a' used after it was moved // CHECK-MESSAGES: [[@LINE-2]]:7: note: move occurred here // CHECK-MESSAGES: [[@LINE-3]]:44: note: the use and move are unsequenced } }