digitalmars.D - Feature request: "noexport" keyword
- Bekenn (42/42) Feb 19 2011 The "export" keyword is a protection attribute, along with "private",
- Nick Sabalausky (9/51) Feb 19 2011 I'm not 100% certain, but I think this should already do what you want:
- Bekenn (13/22) Feb 20 2011 Hmm... I think you may be right. I hadn't considered that, but it makes...
- Nick Sabalausky (8/35) Feb 20 2011 Yea. Actually I just happened to be reading the section about protection...
- Nick Sabalausky (4/44) Feb 20 2011 Keep in mind though, I have *no* idea how "extern(...)" fits in to all o...
- Bernard Helyer (3/5) Feb 20 2011 The linkage is separate to the access and will continue when you change
- Jonathan M Davis (14/67) Feb 19 2011 Just use braces with export. Problem solved.
- Steven Schveighoffer (15/58) Feb 20 2011 I think static should override export. But in any case, attributes are ...
The "export" keyword is a protection attribute, along with "private", "package", "protected", and "public". This means that it can be used with the same syntax as any of those other attributes; for instance, if creating a D "header" for an existing Windows DLL file, you might do something like this: export extern (Windows): void func1(); int func2(); ... This notation is convenient when dealing with a very large existing library; it avoids pointless repetition, and there's no need to keep track of a closing end brace (as there would be with the scoped version). The problem here is that there is no way to cancel an export attribute. Whereas the other protection attributes can be overridden either locally: public: void func1(); package int func2(); ...or globally: public: void func1(); package: int func2(); ...or with a scoped declaration, there is no way to specify that a given symbol should *not* be exported once the "export:" version is used, or inside a scoped export section. A "noexport" keyword would be useful in these situations, if for instance you want to add very small convenience functions that are intended to be inlined and are not actually exported members of the DLL: export extern (Windows): void func1(); int func2(); const(char)* func3(int arg1, int arg2, const(char)* arg3, float arg4, int arg5, void* arg6); noexport const(char)* simpleFunc3(arg3, arg5, arg6) { return func3(0, 0, arg3, 3.14, arg5, arg6); void func4(); ... Currently, to get the same effect, you have to either declare simpleFunc3 above the export: line, use a scoped export block, or put simpleFunc3 in an entirely different file. None of these provide the same level of convenience. What do you guys think?
Feb 19 2011
"Bekenn" <leaveme alone.com> wrote in message news:ijqffm$6lk$1 digitalmars.com...The "export" keyword is a protection attribute, along with "private", "package", "protected", and "public". This means that it can be used with the same syntax as any of those other attributes; for instance, if creating a D "header" for an existing Windows DLL file, you might do something like this: export extern (Windows): void func1(); int func2(); ... This notation is convenient when dealing with a very large existing library; it avoids pointless repetition, and there's no need to keep track of a closing end brace (as there would be with the scoped version). The problem here is that there is no way to cancel an export attribute. Whereas the other protection attributes can be overridden either locally: public: void func1(); package int func2(); ...or globally: public: void func1(); package: int func2(); ...or with a scoped declaration, there is no way to specify that a given symbol should *not* be exported once the "export:" version is used, or inside a scoped export section. A "noexport" keyword would be useful in these situations, if for instance you want to add very small convenience functions that are intended to be inlined and are not actually exported members of the DLL: export extern (Windows): void func1(); int func2(); const(char)* func3(int arg1, int arg2, const(char)* arg3, float arg4, int arg5, void* arg6); noexport const(char)* simpleFunc3(arg3, arg5, arg6) { return func3(0, 0, arg3, 3.14, arg5, arg6); void func4(); ... Currently, to get the same effect, you have to either declare simpleFunc3 above the export: line, use a scoped export block, or put simpleFunc3 in an entirely different file. None of these provide the same level of convenience. What do you guys think?I'm not 100% certain, but I think this should already do what you want: export extern (Windows): void func1(); int func2(); public: void func3(); void func4();
Feb 19 2011
On 2/19/2011 11:30 PM, Nick Sabalausky wrote:"Bekenn"<leaveme alone.com> wrote in message news:ijqffm$6lk$1 digitalmars.com... I'm not 100% certain, but I think this should already do what you want: export extern (Windows): void func1(); int func2(); public: void func3(); void func4();Hmm... I think you may be right. I hadn't considered that, but it makes sense. I was thinking that the "export" attribute was independent of the other protection attributes, which would introduce an asymmetry: private, package, and public could each be overridden by supplying a different protection attribute, but export couldn't be overridden. However, thinking about it, a "private export" wouldn't make much sense (and "export" is listed as a protection attribute, right along with the others), so I guess they must all be mutually exclusive. I just tested this by trying to compile a module with the following line: public export void func(); The compiler rejects it with the message "redundant protection attribute." I think that pretty clearly settles this issue.
Feb 20 2011
"Bekenn" <leaveme alone.com> wrote in message news:ijrjh2$20sv$1 digitalmars.com...On 2/19/2011 11:30 PM, Nick Sabalausky wrote:Yea. Actually I just happened to be reading the section about protection attributes in Andrei's "The D Programming Language" book just the other day, and the way it talked about them indicated they were all mutually-exclusive. Were it not for that, I probably would have made the same assumption as you. Not sure why, though, because as you say, "private/protected export" doesn't seem to make much sence."Bekenn"<leaveme alone.com> wrote in message news:ijqffm$6lk$1 digitalmars.com... I'm not 100% certain, but I think this should already do what you want: export extern (Windows): void func1(); int func2(); public: void func3(); void func4();Hmm... I think you may be right. I hadn't considered that, but it makes sense. I was thinking that the "export" attribute was independent of the other protection attributes, which would introduce an asymmetry: private, package, and public could each be overridden by supplying a different protection attribute, but export couldn't be overridden. However, thinking about it, a "private export" wouldn't make much sense (and "export" is listed as a protection attribute, right along with the others), so I guess they must all be mutually exclusive. I just tested this by trying to compile a module with the following line: public export void func(); The compiler rejects it with the message "redundant protection attribute." I think that pretty clearly settles this issue.
Feb 20 2011
"Nick Sabalausky" <a a.a> wrote in message news:ijs2f1$5ri$1 digitalmars.com..."Bekenn" <leaveme alone.com> wrote in message news:ijrjh2$20sv$1 digitalmars.com...Keep in mind though, I have *no* idea how "extern(...)" fits in to all of this.On 2/19/2011 11:30 PM, Nick Sabalausky wrote:Yea. Actually I just happened to be reading the section about protection attributes in Andrei's "The D Programming Language" book just the other day, and the way it talked about them indicated they were all mutually-exclusive. Were it not for that, I probably would have made the same assumption as you. Not sure why, though, because as you say, "private/protected export" doesn't seem to make much sence."Bekenn"<leaveme alone.com> wrote in message news:ijqffm$6lk$1 digitalmars.com... I'm not 100% certain, but I think this should already do what you want: export extern (Windows): void func1(); int func2(); public: void func3(); void func4();Hmm... I think you may be right. I hadn't considered that, but it makes sense. I was thinking that the "export" attribute was independent of the other protection attributes, which would introduce an asymmetry: private, package, and public could each be overridden by supplying a different protection attribute, but export couldn't be overridden. However, thinking about it, a "private export" wouldn't make much sense (and "export" is listed as a protection attribute, right along with the others), so I guess they must all be mutually exclusive. I just tested this by trying to compile a module with the following line: public export void func(); The compiler rejects it with the message "redundant protection attribute." I think that pretty clearly settles this issue.
Feb 20 2011
On Sun, 20 Feb 2011 16:50:25 -0500, Nick Sabalausky wrote:Keep in mind though, I have *no* idea how "extern(...)" fits in to all of this.The linkage is separate to the access and will continue when you change from export to public.
Feb 20 2011
On Saturday 19 February 2011 23:19:39 Bekenn wrote:The "export" keyword is a protection attribute, along with "private", "package", "protected", and "public". This means that it can be used with the same syntax as any of those other attributes; for instance, if creating a D "header" for an existing Windows DLL file, you might do something like this: export extern (Windows): void func1(); int func2(); ... This notation is convenient when dealing with a very large existing library; it avoids pointless repetition, and there's no need to keep track of a closing end brace (as there would be with the scoped version). The problem here is that there is no way to cancel an export attribute. Whereas the other protection attributes can be overridden either locally: public: void func1(); package int func2(); ...or globally: public: void func1(); package: int func2(); ...or with a scoped declaration, there is no way to specify that a given symbol should *not* be exported once the "export:" version is used, or inside a scoped export section. A "noexport" keyword would be useful in these situations, if for instance you want to add very small convenience functions that are intended to be inlined and are not actually exported members of the DLL: export extern (Windows): void func1(); int func2(); const(char)* func3(int arg1, int arg2, const(char)* arg3, float arg4, int arg5, void* arg6); noexport const(char)* simpleFunc3(arg3, arg5, arg6) { return func3(0, 0, arg3, 3.14, arg5, arg6); void func4(); ... Currently, to get the same effect, you have to either declare simpleFunc3 above the export: line, use a scoped export block, or put simpleFunc3 in an entirely different file. None of these provide the same level of convenience. What do you guys think?Just use braces with export. Problem solved. I can see why noexport could be useful, but there are plenty of other attributes which don't have a negative (e.g. nothrow and pure). If we want to add something like noexport, we probably want a more generic way to do it than adding no export. Of course, I _much_ prefer the way that Linux just exports all symbols, and you don't have have to specify which get exported and which don't (I _hate_ having to deal with that in Windows in C++ - _especially_ since I'm typically doing cross-platform stuff that then uses a macro, and I forget to use it, since it does nothing on Linux, and that's what I'm usually developing on). I hadn't even realized that D _had_ an export keyword. If anything, I'd argue that D should ditch it and just make _everything_ export and be done with it. - Jonathan M Davis
Feb 19 2011
On Sun, 20 Feb 2011 02:19:39 -0500, Bekenn <leaveme alone.com> wrote:The "export" keyword is a protection attribute, along with "private", "package", "protected", and "public". This means that it can be used with the same syntax as any of those other attributes; for instance, if creating a D "header" for an existing Windows DLL file, you might do something like this: export extern (Windows): void func1(); int func2(); ... This notation is convenient when dealing with a very large existing library; it avoids pointless repetition, and there's no need to keep track of a closing end brace (as there would be with the scoped version). The problem here is that there is no way to cancel an export attribute. Whereas the other protection attributes can be overridden either locally: public: void func1(); package int func2(); ...or globally: public: void func1(); package: int func2(); ...or with a scoped declaration, there is no way to specify that a given symbol should *not* be exported once the "export:" version is used, or inside a scoped export section. A "noexport" keyword would be useful in these situations, if for instance you want to add very small convenience functions that are intended to be inlined and are not actually exported members of the DLL: export extern (Windows): void func1(); int func2(); const(char)* func3(int arg1, int arg2, const(char)* arg3, float arg4, int arg5, void* arg6); noexport const(char)* simpleFunc3(arg3, arg5, arg6) { return func3(0, 0, arg3, 3.14, arg5, arg6); void func4(); ... Currently, to get the same effect, you have to either declare simpleFunc3 above the export: line, use a scoped export block, or put simpleFunc3 in an entirely different file. None of these provide the same level of convenience. What do you guys think?I think static should override export. But in any case, attributes are universally applicable in multiple ways (including using scope braces). This would probably solve your problem: extern (Windows): export { void func1(); void func2(); const(char)* func3(int arg1, int arg2, const(char)* arg3, float arg4, int arg5, void* arg6); void func4(); ... } const(char)* simpleFunc3(arg3, arg5, arg6) { return func3(0, 0, arg3, 3.14, arg5, arg6);
Feb 20 2011