J
John Goche
/* Consider the following C snippet: */
Foo *pFoo = NULL;
void FooLength(Foo *pFoo);
void FooHello(Foo **ppFoo);
void FooWorld(Foo **ppFoo);
void FooLength(Foo *pFoo) {
int count = 0;
for (Foo *p = pFoo; *p; p++)
++count;
return count;
}
void FooHello(Foo **ppFoo) {
int count = FooLength(*ppFoo);
// ...
}
void FooWorld(Foo **ppFoo) {
int count = FooLength(*ppFoo);
// ...
}
// Consider the following C++ snippet:
class FooHelloWorld {
public:
void FooHello(Foo **ppFoo) {
iCount = FooLength(*ppFoo);
// ...
}
void FooWorld(Foo **ppFoo) {
// no need to recompute iCount
// ...
}
private:
void FooLength(Foo *pFoo) {
int count = 0;
for (Foo *p = pFoo; *p; p++)
++count;
return count;
}
int iCount;
Foo **ppFoo = NULL;
};
----------------------------------------------------------
We could have done the same in C by adding an extra global
variable or function parameter. However, global variables
tend to pollute, so in C we don't tend to keep too many
of them, and too many function parameters can make a
function too hard to understand. On the other hand
in C++ we can place global variables inside classes
so we can cache results easily without the need to
pollute the global namespace or pass many
arguments around.
I wonder if the C compiler could notice that the same
count value is being reused and automatically optimize
by creating a global variable to hold the value
returned from FooCount. My guess is that it
cannot since it does not know whether the
pFoo linked list will be changed between
the invocations of FooHello and FooWorld.
Regards,
JG
Foo *pFoo = NULL;
void FooLength(Foo *pFoo);
void FooHello(Foo **ppFoo);
void FooWorld(Foo **ppFoo);
void FooLength(Foo *pFoo) {
int count = 0;
for (Foo *p = pFoo; *p; p++)
++count;
return count;
}
void FooHello(Foo **ppFoo) {
int count = FooLength(*ppFoo);
// ...
}
void FooWorld(Foo **ppFoo) {
int count = FooLength(*ppFoo);
// ...
}
// Consider the following C++ snippet:
class FooHelloWorld {
public:
void FooHello(Foo **ppFoo) {
iCount = FooLength(*ppFoo);
// ...
}
void FooWorld(Foo **ppFoo) {
// no need to recompute iCount
// ...
}
private:
void FooLength(Foo *pFoo) {
int count = 0;
for (Foo *p = pFoo; *p; p++)
++count;
return count;
}
int iCount;
Foo **ppFoo = NULL;
};
----------------------------------------------------------
We could have done the same in C by adding an extra global
variable or function parameter. However, global variables
tend to pollute, so in C we don't tend to keep too many
of them, and too many function parameters can make a
function too hard to understand. On the other hand
in C++ we can place global variables inside classes
so we can cache results easily without the need to
pollute the global namespace or pass many
arguments around.
I wonder if the C compiler could notice that the same
count value is being reused and automatically optimize
by creating a global variable to hold the value
returned from FooCount. My guess is that it
cannot since it does not know whether the
pFoo linked list will be changed between
the invocations of FooHello and FooWorld.
Regards,
JG