Final by default?

Paulo Pinto pjmlp at progtools.org
Fri Mar 14 13:45:37 PDT 2014


Am 14.03.2014 19:50, schrieb H. S. Teoh:
> On Fri, Mar 14, 2014 at 07:29:27PM +0100, Paulo Pinto wrote:
>> Am 14.03.2014 19:06, schrieb Iain Buclaw:
>>> On 14 March 2014 17:53, Walter Bright <newshound2 at digitalmars.com> wrote:
>>>> On 3/14/2014 10:26 AM, Johannes Pfau wrote:
>>>>>
>>>>> I use manifest constants instead of version identifiers as well. If
>>>>> a version identifier affects the public API/ABI of a library, then
>>>>> the library and all code using the library always have to be
>>>>> compiled with the same version switches(inlining and templates make
>>>>> this an even bigger problem). This is not only inconvenient, it's
>>>>> also easy to think of examples where the problem will only show up
>>>>> as crashes at runtime.  The only reason why that's not an issue in
>>>>> phobos/druntime is that we only use compiler defined versions
>>>>> there, but user defined versions are almost unusable.
>>>>
>>>>
>>>> Use this method:
>>>>
>>>>
>>>>      --------
>>>>      import wackyfunctionality;
>>>>      ...
>>>>      WackyFunction();
>>>>      --------
>>>>      module wackyfunctionality;
>>>>
>>>>      void WackyFunction() {
>>>>          version (Linux)
>>>>            SomeWackyFunction();
>>>>          else version (OSX)
>>>>              SomeWackyFunction();
>>>>          else
>>>>              ... workaround ...
>>>>      }
>>>>      --------
>>>
>>>
>>> Some years down the line (and some platform testing) turns into:
>>>
>>> --------
>>> module wackyfunctionality;
>>>
>>> void WackyFunction() {
>>>      version (Linux) {
>>>          version (ARM)
>>>              _SomeWackyFunction();
>>>          else version (MIPS)
>>>             MIPS_SomeWackyFunction();
>>>          else version (X86)
>>>             SomeWackyFunction();
>>>          else version (X86_64)
>>>             SomeWackyFunction();
>>>          else
>>>            ... should be some wacky function, but workaround for general case ...
>>>      }
>>>      else version (OSX) {
>>>          version (PPC)
>>>             iSomeWackyFunction();
>>>          else
>>>             SomeWackyFunction();   // In hope there's no other Apple hardware.
>>>      }
>>>      else version (OpenBSD) {
>>>        /// Blah
>>>      }
>>>      else version (Haiku) {
>>>        /// Blah
>>>      }
>>>      else
>>>          ... workaround ...
>>> }
>>> --------
>>>
>>
>>
>> That is why the best approach is to have one module per platform
>> specific code, with a common interface defined in .di file.
>
> +1. Once versioned code gets more than 2 levels deep, it becomes an
> unreadable mess. The .di approach is much more manageable.
>
>
>> Back on my C/C++ days at work, any conditional code would be killed
>> by me during code reviews.
> [...]
>
> Ah, how I wish I could do that... over here at my job, parts of the code
> are a nasty rats'-nest of #if's, #ifdef's, #ifndef's, and "functions"
> that aren't defined anywhere (they are generated by macros, including
> their names!). It used to be relatively sane while the project still
> remained a single project... Unfortunately, about a year or so ago, the
> PTBs decided to merge another project into this one, and by "merge" they
> meant, graft the source tree of the other project into this one, hack it
> with a hacksaw until it compiles, then call it a day. We've been
> suffering from the resulting schizophrenic code ever since, where some
> files are compiled when configuring for platform A, and skipped over and
> some other files are compiled when configuring for platform B (often
> containing conflicting functions of the same name but with incompatible
> parameters), and a ton of #if's and #ifdef's nested to the n'th level
> got sprinkled everywhere in the common code in order to glue the
> schizophrenic mess into one piece. One time, I spent almost an hour
> debugging some code that turned out to be inside an #if 0 ... #endif
> block. >:-(  (The real code had been moved elsewhere, you see, and
> whoever moved the code "kindly" decided to leave the old copy in the
> original file inside an #if 0 block, "for reference", whatever that
> means. Then silly old me came along expecting the code to still be in
> the old place, and sure enough it was -- except that unbeknownst to me
> it's now inside an #if 0 block. Gah!)
>
>
> T
>


Ouch! I feel your pain.

This type of experience is what lead me to fight #ifdef spaghetti code.

--
Paulo


More information about the Digitalmars-d mailing list