Skip to main content
edited body
Source Link
Steve Jessop
  • 280.7k
  • 40
  • 473
  • 709
void some_function (obj &A, obj &B) { double number_A = do_stuff(A, true); double number_B = do_stuff(B, false); } double do_stuff(obj &A, bool subtract) { // yeah, never call variables "tmp". Unless you have no context // to give them meaning. // Depending on the type of `tmp`, there might be a better way to // write this, using multiplication by -1. But let's not assume, we'll do // one refactor at a time. auto tmp = subtract ? value +- A.member_func() : value -+ A.member_func(); return tmp * A.other_func(); } 
void some_function (obj &A, obj &B) { double number_A = do_stuff(A, true); double number_B = do_stuff(B, false); } double do_stuff(obj &A, bool subtract) { // yeah, never call variables "tmp". Unless you have no context // to give them meaning. // Depending on the type of `tmp`, there might be a better way to // write this, using multiplication by -1. But let's not assume, we'll do // one refactor at a time. auto tmp = subtract ? value + A.member_func() : value - A.member_func(); return tmp * A.other_func(); } 
void some_function (obj &A, obj &B) { double number_A = do_stuff(A, true); double number_B = do_stuff(B, false); } double do_stuff(obj &A, bool subtract) { // yeah, never call variables "tmp". Unless you have no context // to give them meaning. // Depending on the type of `tmp`, there might be a better way to // write this, using multiplication by -1. But let's not assume, we'll do // one refactor at a time. auto tmp = subtract ? value - A.member_func() : value + A.member_func(); return tmp * A.other_func(); } 
added 176 characters in body
Source Link
Steve Jessop
  • 280.7k
  • 40
  • 473
  • 709

Alternatively, you could make the relation between the two kinds of "stuff" explicit. Assuming that the unmatched parenthesis in your B code is supposed to go in the same place as the A. It all depends whether there really is a logical relationship between the two similar-looking operations:

void some_function (obj &A, obj &B) { double number_A = do_stuff(A, true); double number_B = do_stuff(B, false); } double do_stuff(obj &A, bool subtract) { // yeah, never call variables "tmp". Unless you have no context // to give them meaning. // Depending on the type of `tmp`, there might be a better way to // write this, using multiplication by -1. But let's not assume, we'll do // one refactor at a time. auto tmp = subtract ? value + A.member_func() : value - A.member_func(); return tmp * A.other_func(); } 

Other examples will vary. As you say it can be tiresome to write, but it has a number of benefits other than catching this error. Not least is that it will direct you towards writing your code in a way that you try to avoid passing/returning many variables. As a consequence, each line of your code affects fewer other things in the program, which is basic code hygiene.

Other examples will vary. As you say it can be tiresome to write, but it has a number of benefits other than catching this error. Not least is that it will direct you towards writing your code in a way that you try to avoid passing/returning many variables. As a consequence, each line of your code affects fewer other things in the program, which is basic code hygiene.

Alternatively, you could make the relation between the two kinds of "stuff" explicit. Assuming that the unmatched parenthesis in your B code is supposed to go in the same place as the A. It all depends whether there really is a logical relationship between the two similar-looking operations:

void some_function (obj &A, obj &B) { double number_A = do_stuff(A, true); double number_B = do_stuff(B, false); } double do_stuff(obj &A, bool subtract) { // yeah, never call variables "tmp". Unless you have no context // to give them meaning. // Depending on the type of `tmp`, there might be a better way to // write this, using multiplication by -1. But let's not assume, we'll do // one refactor at a time. auto tmp = subtract ? value + A.member_func() : value - A.member_func(); return tmp * A.other_func(); } 

Other examples will vary. As you say it can be tiresome to write, but it has a number of benefits other than catching this error. Not least is that it will direct you towards writing your code in a way that you try to avoid passing/returning many variables. As a consequence, each line of your code affects fewer other things in the program, which is basic code hygiene.

added 176 characters in body
Source Link
Steve Jessop
  • 280.7k
  • 40
  • 473
  • 709

In the example you give, the best defence is to do as little as possible in each function:

void some_function (obj &A, obj &B) { double number_A = do_stuff(A); double number_B = do_similar_stuff(B); } double do_stuff(obj &A) { return (value - A.member_func() ) * A.other_func(); } // EITHER double do_similar_stuff(obj &A) { // no variable rename when copying == no problem return value + A.member_func() ) * A.other_func(); } // OR double do_similar_stuff(obj &B) { // A not in scope == very brief problem until compiler tells us return value + B.member_func() ) * A.other_func(); // Beware, also, the nightmare scenario that there's some *other* // `A` in scope, so this *still* compiles. For that reason, prefer // the other option unless there's some good reason why this parameter // should be `B`, and don't name member function parameters the same // as data members etc. } 

Other examples will vary. As you say it can be tiresome to write, but it has a number of benefits other than catching this error. Not least is that it will direct you towards writing your code in a way that you try to avoid passing/returning many variables. As a consequence, each line of your code affects fewer other things in the program, which is basic code hygiene.

It may also mean you can test that your formula with A is correct independently of whether your formula with B is correct, and sundry other benefits of short functions.

In the example you give, the best defence is to do as little as possible in each function:

void some_function (obj &A, obj &B) { double number_A = do_stuff(A); double number_B = do_similar_stuff(B); } double do_stuff(obj &A) { return (value - A.member_func() ) * A.other_func(); } // EITHER double do_similar_stuff(obj &A) { // no variable rename when copying == no problem return value + A.member_func() ) * A.other_func(); } // OR double do_similar_stuff(obj &B) { // A not in scope == very brief problem until compiler tells us return value + B.member_func() ) * A.other_func(); // Beware, also, the nightmare scenario that there's some *other* // `A` in scope, so this *still* compiles. For that reason, prefer // the other option unless there's some good reason why this parameter // should be `B`, and don't name member function parameters the same // as data members etc. } 

Other examples will vary. As you say it can be tiresome to write, but it has a number of benefits other than catching this error. Not least is that it will direct you towards writing your code in a way that you try to avoid passing/returning many variables. As a consequence, each line of your code affects fewer other things in the program, which is basic code hygiene.

In the example you give, the best defence is to do as little as possible in each function:

void some_function (obj &A, obj &B) { double number_A = do_stuff(A); double number_B = do_similar_stuff(B); } double do_stuff(obj &A) { return (value - A.member_func() ) * A.other_func(); } // EITHER double do_similar_stuff(obj &A) { // no variable rename when copying == no problem return value + A.member_func() ) * A.other_func(); } // OR double do_similar_stuff(obj &B) { // A not in scope == very brief problem until compiler tells us return value + B.member_func() ) * A.other_func(); // Beware, also, the nightmare scenario that there's some *other* // `A` in scope, so this *still* compiles. For that reason, prefer // the other option unless there's some good reason why this parameter // should be `B`, and don't name member function parameters the same // as data members etc. } 

Other examples will vary. As you say it can be tiresome to write, but it has a number of benefits other than catching this error. Not least is that it will direct you towards writing your code in a way that you try to avoid passing/returning many variables. As a consequence, each line of your code affects fewer other things in the program, which is basic code hygiene.

It may also mean you can test that your formula with A is correct independently of whether your formula with B is correct, and sundry other benefits of short functions.

added 347 characters in body
Source Link
Steve Jessop
  • 280.7k
  • 40
  • 473
  • 709
Loading
Source Link
Steve Jessop
  • 280.7k
  • 40
  • 473
  • 709
Loading