Summary: Non-C attributes allowed on extern(C) function
           Product: D
           Version: unspecified
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD

--- Comment #0 from Jonathan M Davis <> 2012-04-07 17:32:19 
PDT ---
This compiles:

extern(C) void func(ref int a,
                    out int b,
                    in int* c,
                    scope int* d,
                    immutable int* e);

void main()

which seems pretty atrocious to me. ref, out, in, scope, and immutable do not
exist in C. Other than the fact that D tends to be lax with attributes on
functions (though not generally parameters), I don't know why these would work.

The fact that pure and nothrow work on an extern(C) function is useful, because
it then becomes possible to use them in other pure and nothrow functions, but
that doesn't affect how parameters are passed at all, just how D allows you to
call the function. A similar argument might be made for scope (and therefore
in), but the same cannot be said for ref, out, or immutable. They _do_ affect
the parameters themeselves, not just how the function is called.

Assuming that ref and out really translate to just pointers underneath as
opposed to D doing some extra stuff with them, then translating ref and out to
pointers when generating the code would work, but I'm not sure that that's the
case, and I'd argue that it still makes no sense to allow type modifiers on
extern(C) function parameters which don't exist in C. They're _C_, not _D_. C
has pointers. The function parameters should reflect that. Allowing ref/out on
them buys us little to nothing (assuming that it even works properly) and means
that instead of giving a C function signature, a D function signature is being
given which must be translated to a C function signature.

immutable could just be translated to const, but I'd argue that there's no
point in allowing it, for the same reason - it's not C, and extern(C) functions
are supposed to be C functions.

It's bad enough to allow pure and nothrow on extern(C) functions, but we pretty
much _have_ to in order to avoid a bunch of casting and other such ugliness for
pure/nothrow D functions to use them (though at least with nothrow, you can
catch(Exception) - pure has no such way out). But those have _zero_ affect on
what the actual C function looks like, because they're just additional
attributes that tell the D compiler something about the function, whereas the
ones in the example above affect the actual, C signature.

Is the fact that _any_ such attributes are allowed on extern(C) functions on
purpose? The pages on interfacing with C code don't talk about them, and it
looks like a definite bug to me if they're allowed. I'd be _very_ concerned
about them doing weird things when you actually try and use the extern(C)
function, and I don't like the idea on general principle.

So, either D-specific attributes should be disallowed on extern(C) function
parameters, or they should be explicitly specificied in the spec (including
what they translate to) - and I'd argue that the former is more desirable.

Configure issuemail:
------- You are receiving this mail because: -------

Reply via email to