Skip to main content
added 3 characters in body
Source Link
Eric Lippert
  • 4.1k
  • 9
  • 22

In what cases could allowing them impact program correctness?

I used to work at Coverity, which makes program analysis tools seeking to identify code containing bugs that are (1) plausibly created by real programmers trying to solve real business problems, (2) highly likely to cause end-user-impacting crashes, data loss or incorrect program behaviour, and (3) unlikely to be caught immediately by simply running the code. One such bug which we added a "checker" for during my time there was "late widening conversion".

This happens surprisingly often in C#, Java and similar languages in real-world codebases:

int x = whatever(); 
// ... later, in another part of the codebase ...
double scaled_x = x / 1000;

and the end user is then quite surprised when x is 3141 but x_scaled is 3.000, not 3.141. The meaning of the program is "divide int x by int 1000 to produce a quotient rounded to int, then convert the rounded quotient to double". Plainly the developer intended to write the nigh-indistinguishable:

double scaled_x = x / 1000.0;

which has the meaning "implicitly convert x to double, then divide double by double, and assign the result to scaled_x".

If implicit numeric widening conversions are illegal in the first place then this bug is much less likely. In such a language the developer is encouraged to explicitly convert x to the wider type first.

We saw this defect pattern going from 32 bit integers to 64 bit integers as well; some operation that could overflow a 32 bit int is assigned to a 64 bit localvariable, but the conversion happens after the operation has already potentially overflowed because the developer has gotten confused about when the conversion happens.

In what cases could allowing them impact program correctness?

I used to work at Coverity, which makes program analysis tools seeking to identify code containing bugs that are (1) plausibly created by real programmers trying to solve real business problems, (2) highly likely to cause end-user-impacting crashes, data loss or incorrect program behaviour, and (3) unlikely to be caught immediately by simply running the code. One such bug which we added a "checker" for during my time there was "late widening conversion".

This happens surprisingly often in C#, Java and similar languages in real-world codebases:

int x = whatever(); 
// ... later, in another part of the codebase ...
double scaled_x = x / 1000;

and the end user is then quite surprised when x is 3141 but x_scaled is 3.000, not 3.141. The meaning of the program is "divide int x by int 1000 to produce a quotient rounded to int, then convert the rounded quotient to double". Plainly the developer intended to write the nigh-indistinguishable:

double scaled_x = x / 1000.0;

which has the meaning "implicitly convert x to double, then divide double by double, and assign the result to scaled_x".

If implicit numeric widening conversions are illegal in the first place then this bug is much less likely. In such a language the developer is encouraged to explicitly convert x to the wider type first.

We saw this defect pattern going from 32 bit integers to 64 bit integers as well; some operation that could overflow a 32 bit int is assigned to a 64 bit local, but the conversion happens after the operation has already potentially overflowed because the developer has gotten confused about when the conversion happens.

In what cases could allowing them impact program correctness?

I used to work at Coverity, which makes program analysis tools seeking to identify code containing bugs that are (1) plausibly created by real programmers trying to solve real business problems, (2) highly likely to cause end-user-impacting crashes, data loss or incorrect program behaviour, and (3) unlikely to be caught immediately by simply running the code. One such bug which we added a "checker" for during my time there was "late widening conversion".

This happens surprisingly often in C#, Java and similar languages in real-world codebases:

int x = whatever(); 
// ... later, in another part of the codebase ...
double scaled_x = x / 1000;

and the end user is then quite surprised when x is 3141 but x_scaled is 3.000, not 3.141. The meaning of the program is "divide int x by int 1000 to produce a quotient rounded to int, then convert the rounded quotient to double". Plainly the developer intended to write the nigh-indistinguishable:

double scaled_x = x / 1000.0;

which has the meaning "implicitly convert x to double, then divide double by double, and assign the result to scaled_x".

If implicit numeric widening conversions are illegal in the first place then this bug is much less likely. In such a language the developer is encouraged to explicitly convert x to the wider type first.

We saw this defect pattern going from 32 bit integers to 64 bit integers as well; some operation that could overflow a 32 bit int is assigned to a 64 bit variable, but the conversion happens after the operation has already potentially overflowed because the developer has gotten confused about when the conversion happens.

Source Link
Eric Lippert
  • 4.1k
  • 9
  • 22

In what cases could allowing them impact program correctness?

I used to work at Coverity, which makes program analysis tools seeking to identify code containing bugs that are (1) plausibly created by real programmers trying to solve real business problems, (2) highly likely to cause end-user-impacting crashes, data loss or incorrect program behaviour, and (3) unlikely to be caught immediately by simply running the code. One such bug which we added a "checker" for during my time there was "late widening conversion".

This happens surprisingly often in C#, Java and similar languages in real-world codebases:

int x = whatever(); 
// ... later, in another part of the codebase ...
double scaled_x = x / 1000;

and the end user is then quite surprised when x is 3141 but x_scaled is 3.000, not 3.141. The meaning of the program is "divide int x by int 1000 to produce a quotient rounded to int, then convert the rounded quotient to double". Plainly the developer intended to write the nigh-indistinguishable:

double scaled_x = x / 1000.0;

which has the meaning "implicitly convert x to double, then divide double by double, and assign the result to scaled_x".

If implicit numeric widening conversions are illegal in the first place then this bug is much less likely. In such a language the developer is encouraged to explicitly convert x to the wider type first.

We saw this defect pattern going from 32 bit integers to 64 bit integers as well; some operation that could overflow a 32 bit int is assigned to a 64 bit local, but the conversion happens after the operation has already potentially overflowed because the developer has gotten confused about when the conversion happens.