unnecessary OS redundancy in druntime
Joakim via Digitalmars-d
digitalmars-d at puremagic.com
Sat Dec 13 07:58:28 PST 2014
On Friday, 12 December 2014 at 17:14:01 UTC, Martin Nowak wrote:
> On 12/12/2014 04:47 PM, Joakim wrote:
>> I asked about this on github but didn't get a good answer, so
>> I'm asking
>> here. What's with all the repeated OS blocks in druntime?
>
> No, you don't want to accept the answer. That's slightly
> different than not getting none.
As I alluded to before, saying that the repeated OS blocks are
needed for default cases, which should assert if an OS is not
included in the list, and then admitting that none of them have
such default cases is not a good answer.
> Because it was written before we spread out to multiple
> architectures, and learned hard it is to add something.
None of the linked examples have to do with multiple
architectures either, so this is not going to help you with that.
> We've been through this several times, because the poor guy
> adding support for a new OS or arch has the find all the
> differences through debugging.
The linked examples do not change having to debug in the
slightest. They merely add more work to find all these
version(OS) blocks, for no apparent reason, at least if the
porter wants to be complete with all the files. Or the porter
can just ignore them, since they don't assert anyway.
>> As can be seen from these links, druntime is not consistent in
>> how it's
>
> Have you ever seen software with more than a 100 LOC that's
> totally consistent? There have been many contributors, the
> project is several years old...
I'm well aware of the reasons, but that's no reason not to make
it consistent now.
> > If we can hash out how it should be done, I'll submit a pull
> to
>> fix it up.
>
> There nothing unclear here.
>
> version (A)
> else version (B)
> else static assert(0, "unimplemented");
It is currently unclear when this is actually necessary, as I've
pointed out with my examples. Any Posix OS is free to differ on
any of hundreds of C declarations. Trying to guess ahead of time
where that hypothetical OS might vary seems like premature
optimization to me. In each of the examples I gave, none of the
major Posix OSs differ for those declarations, yet we're
separating them for no reason. Finally, since you admit that
druntime is inconsistent, there must be something "unclear" or
druntime wouldn't be inconsistent.
> As Daniel pointed out, if you run into something that's
> extremely want to save some you might factor out common stuff
> into a default block.
>
> version (A)
> import ...default;
> else version (B)
> import ...default;
> else version (C)
> something else
> else
> static assert(0, "unimplemented");
>
> That's already problematic for a reviewer, because it's much
> harder to check the correctness of a patch (when comparing it
> with the C headers).
Yeah, not going to do that either. My point is that there are
several cases where all this versioning is being done
pointlessly. Doing it once up at the top of the module does not
fix the issue.
On Friday, 12 December 2014 at 18:49:08 UTC, Iain Buclaw via
Digitalmars-d wrote:
> One of the worst I've hit was a crash deep in the start-up
> initialisation
> of Druntime... caused by a totally not obvious struct
> size/align mismatch
> with Cruntime's pthread. Along with not wasting a day
> switching between
> druntime and system C headers, having a compile-time error
> ensures that the
> porter has vetted the correctness of the ported declarations
> and structures.
>
> It may take a while to port all areas, but at least you can be
> mostly
> assured that each step is towards a fully working runtime.
Since none of the examples given would produce compile-time
errors, your claims are wrong.
On Friday, 12 December 2014 at 21:47:37 UTC, Sean Kelly wrote:
> On Friday, 12 December 2014 at 15:47:09 UTC, Joakim wrote:
>> Why not just declare them once for Posix and then specialize
>> for a particular OS later on when necessary
>
> Because therein lies madness.
Yet, that is the way it's currently done for the latter three
examples I gave from druntime.
>> as seems to have been done in these instances?
>
> I could be convinced to allow required function prototypes to be
> in version(Posix) blocks, but never data definitions. And even
> putting function prototypes in common version blocks risks link
> errors. I would *love* it if platforms that contained a header
> actually implemented all of the functions required by a specific
> tag (required, xopen, etc) when choosing any one from that tag,
> but even this can't be relied upon.
Yes, I'm aware of this, as I've seen such unimplemented function
declarations in bionic. But the vast majority of C function
declarations in druntime are already in common version(Posix)
blocks, the one at the top of the module. I'm merely suggesting
we do the same for the few holdouts that are being separated for
no apparent reason. As for data definitions, I don't see why
they're special, but I do notice now that more enums are
separated by OS in druntime.
> In my C/C++ code I have compatibility modules that conditionally
> implement missing functions based on the platform and libc
> version, but this is so not fun. Particularly when you're
> targeting as many platform as D is trying to. So really, you
> should never see a version(Posix) block in core.sys.posix,
> because it means that for some platform, compilation/linking
> will
> fail.
I believe "else version(Posix) {decl;}" is currently used
synonymously for "else {decl;}", merely to underline at that
point in the source that the default case is Posix, even though
it's redundant from the "version (Posix):" at the top of the
module. I understand that you probably don't want either,
whereas I'm suggesting replacing the first three examples with
just a single declaration that's not inside any version block,
except of course the one at the top of the module.
>> As can be seen from these links, druntime is not consistent in
>> how it's separating declarations for different OSs, sometimes
>> using the latter, more compact declarations, other times
>> highly redundant for no apparent reason. If we can hash out
>> how it should be done, I'll submit a pull to fix it up.
>
> It should all be redundant. It makes for large files, but is
> far easier to maintain and debug against than mixing everything
> together.
When should it be redundant, for every single Posix declaration
in druntime? That's far from the case now. When the authors
think a handful of declarations might vary on some future
unspecified platform? Each of the linked examples are separated,
yet none of them vary on any of the 4-5 supported Posix
platforms. In fact, I just checked and none of them are used
anywhere in druntime and phobos, with only IPPROTO_RAW used to
define another unused enum in phobos.
My guess is that you put each of these inside a version(linux)
block just to be safe when you first started druntime, and
porters have since been blindly adding other OSs to the list,
despite the separation serving no real purpose. I have no
problem with having version(OS) blocks where there are actual
differences between the OSs, just not these cases where all the
OSs happen to be the same.
I'm suggesting cleaning up this needless redundancy, to make it
easier for future porters.
More information about the Digitalmars-d
mailing list