|
|
|
|
|
by mjevans
848 days ago
|
|
As a hypothetical, lets assume there's a compiler that has a deep transformation around alloc/reallocs to optimize them when they're only fed 'static' input sizes. // Source by nlewycky
template <typename T> struct vector<t> {
size_t len = 0;
size_t storage_len = 0;
T *storage = nullptr;
void push_back(T t) {
if (len + 1 > storage_len) {
// FIXME: what if storage_len > (size_t_max >> 1) ??
// ? Define maximum expected growth unit? 1K? 4K? 64K?
// Assignment from trinary op visually confusing, add ( )
storage_len = ( storage_len ? storage_len * 2 : 1 );
storage = realloc(storage, storage_len);
}
storage[len] = t;
++len;
}
};
//
vector<t> v;
v.push_back(a);
v.push_back(b);
v.push_back(c);
v.push_back(d);
After inlining all 4 times, the compiler might notice that in this code section vector<t> v always reaches the final size of storage = realloc(storage, 8); and optimize for that. // Pseudo code
template <typename T> vector<T> v = {
// final state at end of code section
size_t len = 4;
size_t storage_len = 8;
T *storage = realloc(NULL, storage_len);
};
// Compiled and included, forgot template function syntax.
void template <typename T> vector<T>.push_back(T t);
(v[0], v[1], v[2], v[3]) = (a, b, c, d);
Even in this case, all the code the programmer wrote was evaluated and had side effects at least once at compile time. No code was eliminated as unreachable / impossible to reach. Instead it was optimized into operations that would always occur, barring realloc failure (which wasn't specified in the toy source, but would probably be a fatal error). |
|