Post by BCSPost by Walter BrightThe right way to do versions that cut across multiple files is to
abstract the versioning into an API, and implement the different
versions in different modules.
What about cases where 90% of the code is identical but small bits and
peaces are different? If I understand correctly, to do what you suggest
would requirer that those bits be put in functions and have several
versions of the function somewhere else. This could be a problem in
several ways
===Tiny bits of code would requirer tiny functions that would hide what
is going on.
Yes, it would require tiny functions, though I don't agree they hide
what is going on. Presumably a descriptive name would be used for it.
One of the nice things about it is that porting the code requires
generating a new module with the right implementations in it, which is a
lot easier than going through checking all the #ifdef's (yes, I know one
shouldn't have to do that, but in practice you ALWAYS have to because
the macros always get misapplied, and often get forgotten to even
apply). With an API, it is difficult to forget to use it, and difficult
to use the wrong macro.
For example, when writing portable C code, one is often faced with the
macros:
__GNUC__ for the Gnu compiler
linux for the host operating system
TARGET_LINUX for the target operating system we're cross compiling for
I can't even count the number of times __GNUC__ was being used to decide
whether we're compiling for windows or linux, or the host operating
system was confused with the target:
#if __GNUC__
#include <pthreads.h>
#else
#include <windows.h>
#endif
AAAARRRRRGGGGGHHHHH!!! That, my friends, is evil.
Now, if one abstracted away what one was *doing* with threads, then one
just does:
import mythreadapi;
and provide a different implementation of mythreadapi for windows or
linux. It's a LOT harder to screw that up.
Post by BCSversion(RowMajor)
x = table[i][j];
else // RowMinor
x = table[j][i];
int GetRow(i,j) { return table[i][j]; }
The function gets inlined.
Post by BCSversion(StrongChecks)
{
if(foo) ...
if(bar) ...
...
}
//empty else
====You can't break across function calls
switch(i)
{
version(Baz)
if(baz) break;
else
break;
...// lots of un versioned code
}
if (globalversion.baz && baz)
break;
Post by BCS====lots of version combinations
version(Foo) i = foo(i);
version(Boo) i = boo(i);
version(Fig) i = fig(i);
version(Baz) i = baz(i);
version(Bar) i = bar(i); //32 options???
i = abc(i); // a different abc is implemented for each version.
Post by BCSAre these valid concerns? Am I misunderstanding what you said?
They are valid concerns, you're just used to thinking in terms of the C
preprocessor.