Redundant code: Difference between revisions

Content deleted Content added
Examples: Simplify example; remove example that is _not_ about redundancy
 
(18 intermediate revisions by 9 users not shown)
Line 1:
In [[computer programming]], '''redundant code''' is [[source code]] or compiled code inthat ais [[computerunnecessary. program]]Code that iscan unnecessary,be suchremoved without affecting its desired behavior is as:redundant.
* recomputing a value that has previously been calculated<ref>[http://doi.acm.org/10.1145/349214.349233 Debray, S. K., Evans, W., Muth, R., and De Sutter, B. 2000. Compiler techniques for code compaction. ACM Trans. Program. Lang. Syst. 22, 2 (Mar. 2000), 378–415.]</ref> and is still available,
* code that is never executed (known as [[unreachable code]]),
* code which is executed but has no external effect (e.g., does not change the output produced by a program; known as [[dead code]]).
 
==Categories==
A [[NOP (code)|NOP]] instruction might be considered to be redundant code that has been explicitly inserted to pad out the [[instruction (computer science)|instruction]] stream or introduce a time delay, for example to create a timing loop by "wasting time". [[Identifier]]s that are declared, but never referenced, are termed '''redundant declarations'''.
Noteble categoreis of redundant code include:
 
*; recomputingRecomputing: Recomputing a value that has previously been calculated<ref>[http://doi.acm.org/10.1145/349214.349233 Debray, S. K., Evans, W., Muth, R., and De Sutter, B. 2000. Compiler techniques for code compaction. ACM Trans. Program. Lang. Syst. 22, 2 (Mar. 2000), 378–415.]</ref> and is still available, .
==Examples==
<source lang="C">
int foo(int iX)
{
int iY = iX*2;
 
*; [[Dead code]]: Code whichthat is executed but has no external effect; (e.g., does not change the output produced by a program;. known as [[dead code]]).
return iX*2;
}
</source>
 
; [[Unreachable code]]: Code that is never executed. Also, called dead code.
The second <tt>iX*2</tt> expression is redundant code and can be replaced by a reference to the variable <tt>iY</tt>. Alternatively, the definition <tt>int iY = iX*2</tt> can instead be removed.
 
; [[NOP (code)|NOP]] padding: A NOP instruction might be considered redundant if it's for padding. But if the NOP is required for proper functionality then it's not redundant.
Consider:
 
; Unused [[identifier]]: Declared, but never referenced is a redundant declaration.
<source lang="C">
#define min(A,B) ((A)<(B)?(A):(B))
 
==Examples==
int shorter_magnitude(int u1, int v1, int u2, int v2)
In the following [[C (computer language)|C]] code, the second <code>x * 2</code> expression is redundant code. Line 2 can be removed, or alternatively, line 3 can be changed to {{code| return y;}}.
{
 
/* Returns the shorter magnitude of (u1,v1) and (u2,v2) */
<syntaxhighlight lang="C" line>
return sqrt(min(u1*u1 + v1*v1, u2*u2 + v2*v2));
int foo(int iXx) {
int iYy = iXx * 2;
return iXx * 2;
}
</syntaxhighlight>
</source>
 
AsA amore consequencesubtle ofexample usinginvolves the [[C preprocessor]], thethat compilerinserts willcode only witness thebefore expandedcompilation. formConsider:
 
<sourcesyntaxhighlight lang="C">
#define min(A,B) ((A)<(B)?(A):(B))
int shorter_magnitude(int u1, int v1, int u2, int v2)
int shorter_magnitude(int u1a, int v1b, int u2c, int v2d) {
{
return sqrt(min(u1a*u1a + v1b*v1b, u2c*u2c + v2d*v2d));
int temp;
if (u1*u1 + v1*v1 < u2*u2 + v2*v2)
temp = u1*u1 + v1*v1; /* Redundant */
else
temp = u2*u2 + v2*v2; /* Redundant */
return sqrt(temp);
}
</syntaxhighlight>
</source>
 
After preprocessing, the code expands to code that evaluates both {{code|a*a + b*b}} and {{code|c*c + d*d}} twice. To eliminate the duplicate code, the macro {{code|min}} could ge converted to a function.
Because the use of min/max macros is very common, modern compilers are trained to recognize and eliminate redundancy caused by their use.
 
<sourcesyntaxhighlight lang="C">
There is ''no'' redundancy, however, in the following code:
int shorter_magnitude(int u1a, int v1b, int u2c, int v2d) {
<source lang="C">
return sqrt(((a*a + b*b)<(c*c + d*d)?(a*a + b*b):(c*c + d*d)));
#define max(A,B) ((A)>(B)?(A):(B))
 
int random(int cutoff, int range)
{
/* Returns (cutoff, cutoff, cutoff, ...,
cutoff+1, cutoff+2, ... range) */
return max(cutoff, rand()%range);
}
</syntaxhighlight>
</source>
 
The reason is that its implementation is incorrect. If the initial call to rand(), modulo range, is greater than or equal to cutoff, rand() will be called a second time for a second computation of rand()%range, which may result in a value that is actually lower than the cutoff. The max macro will thus not work for this function.
 
==See also==
* {{Annotated link |Code bloat}}
 
* [[{{Annotated link |Code bloat]]reuse}}
* {{Annotated link |Common subexpression elimination}}
* [[Duplicate code]]
* {{Annotated link |Don't repeat yourself}}
* [[{{Annotated link |Duplicate code]]}}
* {{Annotated link |Redundancy (information theory)}}
* {{Annotated link |Code refactoring}}
* {{Annotated link |Code smell}}
 
==References==