Thread overview | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
April 08, 2012 [Issue 7854] New: Non-C attributes allowed on extern(C) function parameters | ||||
---|---|---|---|---|
| ||||
http://d.puremagic.com/issues/show_bug.cgi?id=7854 Summary: Non-C attributes allowed on extern(C) function parameters Product: D Version: unspecified Platform: All OS/Version: All Status: NEW Severity: normal Priority: P2 Component: DMD AssignedTo: nobody@puremagic.com ReportedBy: jmdavisProg@gmx.com --- Comment #0 from Jonathan M Davis <jmdavisProg@gmx.com> 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: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
April 09, 2012 [Issue 7854] Non-C attributes allowed on extern(C) function parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | http://d.puremagic.com/issues/show_bug.cgi?id=7854 Don <clugdbug@yahoo.com.au> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |clugdbug@yahoo.com.au --- Comment #1 from Don <clugdbug@yahoo.com.au> 2012-04-08 23:09:26 PDT --- This is part of the general spec bug that extern(C) is almost completely undocumented. Eg, what does this do? extern(C) void func(lazy int x); -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
April 12, 2012 [Issue 7854] Non-C attributes allowed on extern(C) function parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | http://d.puremagic.com/issues/show_bug.cgi?id=7854 Steven Schveighoffer <schveiguy@yahoo.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |schveiguy@yahoo.com Component|DMD |websites --- Comment #2 from Steven Schveighoffer <schveiguy@yahoo.com> 2012-04-12 11:55:47 PDT --- extern(C) does not have any effect on parameters. Note that you can easily implement extern(C) functions in D (in fact the runtime heavily relies on this). AFAICT, it basically is just a way to treat the symbol as demangled. Also note that because C treats fixed-sized array parameters as pointers, and D treats them as values, the following idiom has emerged, which would not be possible if ref wasn't allowed: extern(C) int pipe(ref int[2] fds); Changing to websites, since this is really a spec issue. The compiler is implemented properly IMO. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
April 12, 2012 [Issue 7854] Non-C attributes allowed on extern(C) function parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | http://d.puremagic.com/issues/show_bug.cgi?id=7854 Don <clugdbug@yahoo.com.au> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |spec Component|websites |DMD --- Comment #3 from Don <clugdbug@yahoo.com.au> 2012-04-12 12:56:33 PDT --- (In reply to comment #2) > extern(C) does not have any effect on parameters. Not so. It most definitely does! Doesn't make much difference on Linux, but on Windows they are quite different. Also variadic functions are defined in the spec to be different for extern(C) vs extern(D), on all platforms. > Note that you can easily > implement extern(C) functions in D (in fact the runtime heavily relies on > this). I know, and it worries me. The question is, is that just implementation-specific behaviour? > Also note that because C treats fixed-sized array parameters as pointers, and D treats them as values, the following idiom has emerged, which would not be possible if ref wasn't allowed: > > extern(C) int pipe(ref int[2] fds); Yeah, and that's nice. But the odd thing is, that is actually implementable in C. Whereas other things, such as lazy, might not be. The key issue is, should extern(C) allow signatures that *cannot* be implemented in C? > Changing to websites, since this is really a spec issue. The compiler is implemented properly IMO. I agree it is probably a spec issue. Spec issues are normally treated with DMD + spec keyword. It is part of the DMD download. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
April 12, 2012 [Issue 7854] Non-C attributes allowed on extern(C) function parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | http://d.puremagic.com/issues/show_bug.cgi?id=7854 --- Comment #4 from Steven Schveighoffer <schveiguy@yahoo.com> 2012-04-12 14:20:09 PDT --- (In reply to comment #3) > > I agree it is probably a spec issue. Spec issues are normally treated with DMD + spec keyword. It is part of the DMD download. From description in bugzilla for websites component: "Problems with the contents of www.digitalmars.com and www.d-programming-language.org, including the language specification" If what you say is true, we should probably update the component description. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
April 12, 2012 [Issue 7854] Non-C attributes allowed on extern(C) function parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | http://d.puremagic.com/issues/show_bug.cgi?id=7854 --- Comment #5 from Steven Schveighoffer <schveiguy@yahoo.com> 2012-04-12 14:28:18 PDT --- (In reply to comment #3) > (In reply to comment #2) > > extern(C) does not have any effect on parameters. > > Not so. It most definitely does! Doesn't make much difference on Linux, but on Windows they are quite different. Also variadic functions are defined in the spec to be different for extern(C) vs extern(D), on all platforms. I'm not exactly talking about binding or calling convention, I'm more talking about types. To me, the two are orthogonal. And I don't see why lazy would be any different for extern(C) than it is for D, all the hard work is done by the caller. It's just that the type is really transformed into a delegate. variadic functions of course are different and defined differently, no argument there. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
April 13, 2012 [Issue 7854] Non-C attributes allowed on extern(C) function parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | http://d.puremagic.com/issues/show_bug.cgi?id=7854 --- Comment #6 from Jonathan M Davis <jmdavisProg@gmx.com> 2012-04-12 23:07:41 PDT --- < I'm not exactly talking about binding or calling convention, I'm more talking < about types. To me, the two are orthogonal. Whereas I would argue that since you're declaring a C function, it should be a _C_ function and therefore not include features which C doesn't have. The only reason that I think that permitting pure and nothrow on C functions makes any sense is out of pure necessity. > extern(C) int pipe(ref int[2] fds); I would expect this to simply be extern(C) int pipe(int* fds); because what C does is pass a pointer, not a fixed-size array. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
April 15, 2012 [Issue 7854] Non-C attributes allowed on extern(C) function parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | http://d.puremagic.com/issues/show_bug.cgi?id=7854 Maxim Fomin <maxim@maxim-fomin.ru> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |maxim@maxim-fomin.ru --- Comment #7 from Maxim Fomin <maxim@maxim-fomin.ru> 2012-04-14 22:29:04 PDT --- (In reply to comment #3) > (In reply to comment #2) > > extern(C) does not have any effect on parameters. > > Not so. It most definitely does! Doesn't make much difference on Linux, but on Windows they are quite different. Also variadic functions are defined in the spec to be different for extern(C) vs extern(D), on all platforms. > And how does it affect? In most cases what I found about externs in D, C++, C they all are about linkage. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
April 15, 2012 [Issue 7854] Non-C attributes allowed on extern(C) function parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | http://d.puremagic.com/issues/show_bug.cgi?id=7854 --- Comment #8 from Maxim Fomin <maxim@maxim-fomin.ru> 2012-04-15 01:15:46 PDT --- When extern(C) appears it boils down to: 1) either it is used with purely C features: extern (C) int *array_func (int *array, size_t size); This is heavily used when interfacing D code with C libraries and vice versa. 2) or it is used with non-C features: extern (C) int[] array_func (int[] array); Assumptions here are following: - array_func is in different object file which was made (possibly) by different implementation of which current source code is compiled (it may be even not D); - such another implemenation mangles names differently, to overcome this obstacle there is need to remove any mangling; - but such implementation handles at least arrays (as in the example) equally with current implementation. As new features would be introduced in declaration, more features should be treated equally. Although compiler (and programmer) can distinguish among 1) and 2) the problem is worsen by the fact that much depends on what will be happening after compilation and compiler cannot solve such things. Shortly speaking, the fact that dmd allows such thing is a loophole to link D code with something that couldn't be used directly but has something common with current implementation of D and is worth using. It is an option, and it is a tradeoff between possible benefits and bugs. I do not know about any benefits which it gives now, but it may change in the future. The first idea is that different D compilers may mangle names differently, but ABI page at dlang.org states that all implementations should conform to one mangling standard. However, it is not official standard and nobody can enforce to follow it. Speaking about possible bugs it is clear that they are obvious (in majority cases the code with 2) even wouldn't contain hidden bug but would not work). So, code containing something like 2) means that it was written by somebody who either knows what he is he doing, or is looking for problems. Possible solutions: 1) forbid non-C features in extern(C) as it was suggested. D code could be linked only with C, D (suggesting that every D implementation follows abi page, otherwise D community would have big problem) and any other language which can be interfaced in C way. 2) leave the situation as it is. The only problem would come from code written by people who experince difficulties in distinguishing D and C 3) forbid non-C features in extern(C) as it was suggested but introduce directive that instructs compiler not to mangle function names. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
April 16, 2012 [Issue 7854] Non-C attributes allowed on extern(C) function parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | http://d.puremagic.com/issues/show_bug.cgi?id=7854 --- Comment #9 from Steven Schveighoffer <schveiguy@yahoo.com> 2012-04-16 05:43:17 PDT --- (In reply to comment #6) > > I'm not exactly talking about binding or calling convention, I'm more talking about types. To me, the two are orthogonal. > > Whereas I would argue that since you're declaring a C function, it should be a _C_ function and therefore not include features which C doesn't have. The only reason that I think that permitting pure and nothrow on C functions makes any sense is out of pure necessity. No. An extern(C) function does not mean it's a C function. It just means it has C linkage. See here: http://dlang.org/attribute.html#linkage extern(C) has nothing to do with parameters, only calling conventions. What would you expect here? extern(C) void foo(long); to accept 32-bit or 64-bit integer? The answer is, 64 bit. The confusion that would abound if you had to use C's types and keywords whenever declaring an extern(C) function would be not worth the trouble. The one exception, as Don pointed out, is variadic arguments, but that is covered here: http://dlang.org/function.html#variadic > > extern(C) int pipe(ref int[2] fds); > > I would expect this to simply be > > extern(C) int pipe(int* fds); > > because what C does is pass a pointer, not a fixed-size array. This does not say anything about the size. Even though it's a 'hint' in C, it's enforceable in D. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
Copyright © 1999-2021 by the D Language Foundation