D - some questions concerning D specs
- Pavel \"EvilOne\" Minayev (41/41) Nov 07 2001 There are some things there that just aren't
- Walter (20/61) Nov 08 2001 Yes, yes!
- Pavel \"EvilOne\" Minayev (23/51) Nov 08 2001 gets
- Russ Lewis (15/17) Nov 08 2001 The copying code isn't the problem. It's the allocation code. Presumab...
- Walter (10/56) Nov 09 2001 In general, if an exception will be thrown if checking is turned on,
- Sean L. Palmer (2/11) Nov 09 2001 Are you saying that D supports use of the :: operator?
- Walter (3/15) Nov 09 2001 No, sorry, A::B() is not allowed. Use A.B()
- Pavel \"EvilOne\" Minayev (31/32) Nov 08 2001 Here are some more:
- Russ Lewis (16/40) Nov 08 2001 Since you know the module name, why not:
- Pavel \"EvilOne\" Minayev (18/32) Nov 09 2001 And what if there's a local variable or class property
- Russ Lewis (13/22) Nov 09 2001 Frankly, then you are a bad programmer :) Seriously, though, I suppose
- Pavel \"EvilOne\" Minayev (6/13) Nov 09 2001 Definitely. However, we shouldn't discriminate =)
- Walter (7/43) Nov 09 2001 Hmm. It might be a good idea to use the "." as meaning "at the module
- Walter (10/39) Nov 09 2001 Public. I always thought that C++'s way just made for annoying extra typ...
- Pavel \"EvilOne\" Minayev (7/15) Nov 09 2001 Yes, yes!
- Walter (4/19) Nov 09 2001 I'm more interested in compelling arguments (!)
- Pavel \"EvilOne\" Minayev (6/9) Nov 09 2001 This works if A is a direct successor of B. However, the
- Walter (4/14) Nov 10 2001 A.super.dee.duper.B()
- a (10/22) Nov 10 2001 How about I call my family in New Jersey? :-) Seriously though, in
- Pavel \"EvilOne\" Minayev (14/15) Nov 11 2001 Suppose we have the following code:
- Roberto Mariottini (11/26) Nov 12 2001 PLEASE don't do that!
- Pavel \"EvilOne\" Minayev (9/15) Nov 12 2001 to
- Roland (3/18) Nov 12 2001 me too
- Walter (3/18) Nov 29 2001 I think you're right.
- Robert W. Cunningham (12/36) Nov 29 2001 Seconded!
- Ben Cohen (9/15) Nov 30 2001 Yes, I agree with this, for several reasons. It simplifies the language...
- Roland (8/12) Nov 30 2001 Yes: pointers are types.
- Russ Lewis (12/14) Nov 30 2001 Are you stating that it currently is a syntax error, or that you think i...
- nancyetroland (8/14) Nov 29 2001 Should be.
- Russ Lewis (18/18) Nov 30 2001 The key issue to me here is the parsing of tokens. As I understand C pa...
- nancyetroland (21/46) Dec 01 2001 I thought whitespaces were separators un C.
- Russ Lewis (8/8) Dec 01 2001 I agree with the sentiment. It will just need comments from some more k...
- Walter (10/13) Dec 01 2001 knowledge able
- Pavel Minayev (8/14) Dec 02 2001 functions.
- Pavel Minayev (3/3) Dec 02 2001 And for pointers to methods, I'd suggest
-
Walter
(3/6)
Dec 02 2001
I'm trying to avoid pointers to members
. - Pavel Minayev (60/66) Dec 02 2001 A question then.
- Walter (9/15) Dec 03 2001 What you could do is create an array of function pointers, indexed by th...
- Sean L. Palmer (16/31) Dec 03 2001 Been there, done that, in Pascal and C. Interfacing to Windows User. T...
- Pavel Minayev (19/32) Dec 03 2001 That
- Walter (4/6) Dec 03 2001 Member function pointers are confusing (to me, anyway), and there's some
- Pavel Minayev (10/16) Dec 03 2001 I agree that _C++_ method pointers are confusing. But what's wrong
- Walter (4/9) Dec 04 2001 You have to generate things like thunks. Ugh.
- Pavel Minayev (35/36) Dec 04 2001 I've probably explained the thing badly.
- Roland (65/97) Dec 11 2001 Yes, this is a common problem having an object that trap events or
- Pavel Minayev (16/31) Dec 12 2001 The problem here is that it's not very easy to find out if some
- NancyEtRoland (130/142) Dec 22 2001 Franckly, if i understand well the concept, i had to remind pointer
- Pavel Minayev (16/21) Dec 23 2001 Exactly what I proposed.
- NancyEtRoland (5/18) Dec 26 2001 Putting those pointers to vtable is in fact exactely the same (even if i...
- Russ Lewis (39/39) Dec 25 2001 Pavel makes a critical point here that must be noted. Callbacks, very
- NancyEtRoland (6/34) Dec 26 2001 That is some kind of code we all do and i would apreciate a compiler do ...
- Russ Lewis (22/24) Dec 26 2001 I have implemented the following in C++:
- Pavel Minayev (12/25) Dec 26 2001 returns an
- Russ Lewis (12/12) Dec 26 2001 My code has to be portable between gcc on Linux and MSVC on Windows. Th...
- Sean L. Palmer (17/18) Dec 02 2001 I am not sure why you would want to avoid pointers to member functions.....
- Pavel Minayev (6/20) Dec 02 2001 Yeah, syntax is a question.
- a (5/8) Dec 02 2001 So can operator overloading. So can the preprocesser. So can multiple
- Charles Hixson (6/12) Dec 03 2001 I assume that in a real example the args would be spelled out?
- Pavel Minayev (5/9) Dec 03 2001 int.(int.(int) method1, void.(float, float), char[]) theFunc;
- Russ Lewis (10/15) Dec 03 2001 A couple of other brainstorms:
- Roland (5/16) Dec 04 2001 int function(args)* fp1,fp2; // requires new keyword 'function'
- Walter (3/7) Nov 30 2001 Yeah, that should be an error. -Walter
- Russ Lewis (6/11) Nov 09 2001 Persuade, persuade, persuade, persuade. Is that enough, or do we need m...
- Russell Borogove (4/13) Nov 09 2001 I'd personally lobby for the default attribute be "compilererror".
- Sean L. Palmer (20/32) Nov 09 2001 typing
- Walter (7/30) Nov 09 2001 say
- la7y6nvo shamko.com (30/37) Nov 10 2001 I would argue in favor of breaking with tradition on the 'int *x, y;'
- Axel Kittenberger (11/20) Nov 12 2001 I say private would be better for quality code.
- Roberto Mariottini (6/20) Nov 12 2001 I think the compiler shouldn't compile a class with no 'public', 'privat...
- Pavel \"EvilOne\" Minayev (10/18) Nov 12 2001 point
- Pavel \"EvilOne\" Minayev (12/12) Nov 08 2001 What is the default calling convention for D functions -
- Sean L. Palmer (11/23) Nov 08 2001 Don't you find it the least bit presumptuous to make a calling conventio...
- Pavel \"EvilOne\" Minayev (8/16) Nov 08 2001 Yes, I know that it isn't actually "std". But it is well known as such,
- Walter (18/30) Nov 09 2001 None of them. I intend to have it (the default D calling convention)
- Pavel \"EvilOne\" Minayev (23/34) Nov 09 2001 the
- Walter (8/14) Nov 09 2001 If you are writing assembler routines, the options are:
- Pavel \"EvilOne\" Minayev (5/9) Nov 09 2001 BTW what's the point in caller cleaning the stack? I always thought
- Walter (5/14) Nov 10 2001 conventions
- Russell Borogove (5/11) Nov 09 2001 So any external code that calls into D code can only safely do
- Walter (6/15) Nov 09 2001 the
- Ben Cohen (6/7) Nov 08 2001 If you have public and private (etc.) attributes, you no longer appear t...
- Pavel \"EvilOne\" Minayev (4/9) Nov 08 2001 ^^^^^
- Pavel \"EvilOne\" Minayev (13/13) Nov 09 2001 I believe that extern() property states that function
- Walter (7/21) Nov 09 2001 It is legal, despite what the doc says (!).
- Pavel \"EvilOne\" Minayev (37/45) Nov 09 2001 My suggestion would be something like:
- Pavel \"EvilOne\" Minayev (2/2) Nov 10 2001 BTW in C++Builder, pointers to methods are declared
- Pavel \"EvilOne\" Minayev (27/27) Nov 10 2001 On second thought, I came to an idea that it'd be nice
- Pavel \"EvilOne\" Minayev (1/1) Nov 13 2001 Sooo?
- OddesE (11/12) Feb 05 2002 I am with this on Pavel.
- Pavel \"EvilOne\" Minayev (2/2) Nov 10 2001 If module B imports module C, and module A
- Walter (3/5) Nov 10 2001 Scoping issues aside, yes.
- Pavel \"EvilOne\" Minayev (10/15) Nov 11 2001 So there's no way to import a module for my own,
- Walter (3/19) Nov 19 2001 Hmm, private imports. That might be a good idea!
- Ben Cohen (3/5) Nov 20 2001 Actually, could you explain why public imports are a good idea (in
- Pavel Minayev (4/9) Nov 20 2001 I agree. Module imports must be private by default. This
- Walter (3/7) Nov 20 2001 We obviously are approaching this from different directions :-)
- Ben Cohen (19/24) Nov 21 2001 Yes, I think so too. OK then, first I'll explain why I think private im...
- Russ Lewis (21/21) Nov 21 2001 Overall, I like this idea a lot. However, I would note that, unlike inh...
-
Walter
(5/7)
Nov 22 2001
Actually, D does
. The idea is to minimize the fluff for quick & dirt...
There are some things there that just aren't clear enough... Complex arrays. Judging by the specs, int[]* is a pointer to array, int*[] is an array of pointers. Is int[]*[] a legal way to declare an array of pointers to arrays? Is int*[]* a legal way to declare a pointer to array of pointers? Static attribute. Are static local variables supported? Array slicing. What happens when I use the form a[x..y], and x is greater than y? Class model. It says that for each class XXXX, an instance of Class is created, named ClassXXXX. What is Class (RTTI, I believe), what functionality it provides? If I have a reference to object, how do I get the appropriate Class object? Is it possible to construct an object without knowing its type at compile-time, via its Class (like in Delphi)? Distinguishing between . and -> It is stated that there is no need for -> in D, since it's clear to the compiler whether we access fields directly or through pointer. But specification contains the following definition: PostfixExpression: PrimaryExpression PostfixExpression . Identifier PostfixExpression -> Identifier (!?) A mistake? Methods of base class. How do I access them? I believe that super.method form is used to call methods of super class. But how to call a method of an arbitrary class in the hierarchy - super(class).method? Static methods. Can they be overridden? Can they be called in the same manner as non-static ones? Modules. According to specification, "Modules have a one- to-one correspondence with source files. The module name is the file name with the path and extension stripped off." Does this mean that module names are case-insensitive on Windows and case-sensitive on *nix? If not, how is it achieved? ... to be continued ... =)
Nov 07 2001
"Pavel "EvilOne" Minayev" <evilone omen.ru> wrote in message news:9sb0c1$ceq$1 digitaldaemon.com...Complex arrays. Judging by the specs, int[]* is a pointer to array, int*[] is an array of pointers. Is int[]*[] a legal way to declare an array of pointers to arrays? Is int*[]* a legal way to declare a pointer to array of pointers?Yes, yes!Static attribute. Are static local variables supported?Yes.Array slicing. What happens when I use the form a[x..y], and x is greater than y?If you have array bounds checking turned on, an array bounds exception gets thrown.Class model. It says that for each class XXXX, an instance of Class is created, named ClassXXXX. What is Class (RTTI, I believe), what functionality it provides?A way to examine the type and offset of each member, access to the finalizer, and (in the future) access to any classes it depends on.If I have a reference to object, how do I get the appropriate Class object?There's a member function to get it. Or a property. I can't decide which <g>.Is it possible to construct an object without knowing its type at compile-time, via its Class (like in Delphi)?That sounds like a good idea.Distinguishing between . and -> It is stated that there is no need for -> in D, since it's clear to the compiler whether we access fields directly or through pointer. But specification contains the following definition: PostfixExpression: PrimaryExpression PostfixExpression . Identifier PostfixExpression -> Identifier (!?) A mistake?Yes.Methods of base class. How do I access them? I believe that super.method form is used to call methods of super class. But how to call a method of an arbitrary class in the hierarchy - super(class).method?If class B is derived from A, you can also use: B b; b.A.foo();Static methods. Can they be overridden? Can they be called in the same manner as non-static ones?Yes, yes.Modules. According to specification, "Modules have a one- to-one correspondence with source files. The module name is the file name with the path and extension stripped off." Does this mean that module names are case-insensitive on Windows and case-sensitive on *nix? If not, how is it achieved?Module names are case sensitive. On windows, this means that you cannot have two modules that differ only in case. While not elegant, I doubt it will be a significant problem in practice.... to be continued ... =)Great questions!
Nov 08 2001
"Walter" <walter digitalmars.com> wrote in message news:9sdc1v$2167$1 digitaldaemon.com...getsArray slicing. What happens when I use the form a[x..y], and x is greater than y?If you have array bounds checking turned on, an array bounds exceptionthrown.And if not? I mean, since the copying code will, in general, be the loop (or am I wrong?), it simply won't do anything.Ability to call methods of class by their name (a la IDispatch::Invoke)? Also, if those Class objects are unused, will they still be there (thus cluttering the program with unnecessary info like class and method names)?Class model. It says that for each class XXXX, an instance of Class is created, named ClassXXXX. What is Class (RTTI, I believe), what functionality it provides?A way to examine the type and offset of each member, access to the finalizer, and (in the future) access to any classes it depends on.object.class, probably?If I have a reference to object, how do I get the appropriate Class object?There's a member function to get it. Or a property. I can't decide which <g>.This, however, involves things like virtual constructors.Is it possible to construct an object without knowing its type at compile-time, via its Class (like in Delphi)?That sounds like a good idea.So, from withing B, I'd simply write: A.foo();Methods of base class. How do I access them? I believe that super.method form is used to call methods of super class. But how to call a method of an arbitrary class in the hierarchy - super(class).method?If class B is derived from A, you can also use: B b; b.A.foo();So the following: class A { static void B() { ... } } A a; A::B(); a.B(); // the same? is legal? If it is, will B() be aware that it is called in a different way?Static methods. Can they be overridden? Can they be called in the same manner as non-static ones?Yes, yes.
Nov 08 2001
Pavel \"EvilOne\" Minayev wrote:And if not? I mean, since the copying code will, in general, be the loop (or am I wrong?), it simply won't do anything.The copying code isn't the problem. It's the allocation code. Presumably, the compiler views all indices as unsigned values. Similarly, the size parameter in the compiler equivalent of malloc() is unsigned. So take 1-3, with both numbers viewed as (perhaps) unsigned 32 bit ints, what do you get? IIRC, something near 4 billion elements. So the compiler tries to allocate 4 billion elements * x bytes per element = many many many bytes. In most architectures, this ends up throwing an OutOfMemory exception. But in some...where you have access to multiple GB of virtual memory...we consume an unbelievable quantity of memory. :( -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Nov 08 2001
"Pavel "EvilOne" Minayev" <evilone omen.ru> wrote in message news:9sdfh6$253c$1 digitaldaemon.com..."Walter" <walter digitalmars.com> wrote in message news:9sdc1v$2167$1 digitaldaemon.com...In general, if an exception will be thrown if checking is turned on, undefined behavior will result if checking is turned off.getsArray slicing. What happens when I use the form a[x..y], and x is greater than y?If you have array bounds checking turned on, an array bounds exceptionthrown.And if not? I mean, since the copying code will, in general, be the loop (or am I wrong?), it simply won't do anything.That's an open possibility.Ability to call methods of class by their name (a la IDispatch::Invoke)?Class model. It says that for each class XXXX, an instance of Class is created, named ClassXXXX. What is Class (RTTI, I believe), what functionality it provides?A way to examine the type and offset of each member, access to the finalizer, and (in the future) access to any classes it depends on.Also, if those Class objects are unused, will they still be there (thus cluttering the program with unnecessary info like class and method names)?Yes.Or .classinfo. Something like that.object.class, probably?If I have a reference to object, how do I get the appropriate Class object?There's a member function to get it. Or a property. I can't decide which <g>.Yes.So, from withing B, I'd simply write: A.foo();Methods of base class. How do I access them? I believe that super.method form is used to call methods of super class. But how to call a method of an arbitrary class in the hierarchy - super(class).method?If class B is derived from A, you can also use: B b; b.A.foo();Yes.So the following: class A { static void B() { ... } } A a; A::B(); a.B(); // the same?Static methods. Can they be overridden? Can they be called in the same manner as non-static ones?Yes, yes.is legal? If it is, will B() be aware that it is called in a different way?Yes, yes.
Nov 09 2001
Are you saying that D supports use of the :: operator? SeanSo the following: class A { static void B() { ... } } A a; A::B(); a.B(); // the same?Yes.
Nov 09 2001
"Sean L. Palmer" <spalmer iname.com> wrote in message news:9sh8nm$237g$1 digitaldaemon.com...No, sorry, A::B() is not allowed. Use A.B()Are you saying that D supports use of the :: operator? SeanSo the following: class A { static void B() { ... } } A a; A::B(); a.B(); // the same?Yes.
Nov 09 2001
... to be continued ... =)Here are some more: What is the default attribute for class members (private/protected/public)? Suppose I have the following declaration: int* x, y; Is y an int or a pointer to int? Once again, suppose there's a piece of code like that: void X() { ... } class B { void Y() { ... } } class C { void Y() { ... } } class A: B { void X() { ... } void Y() { C B; B.Y(); X(); } } simply typing X() would invoke A.X())? (since B.Y() will invoke method Y() of object C)? ... to be continued ... =)
Nov 08 2001
Pavel \"EvilOne\" Minayev wrote:Once again, suppose there's a piece of code like that: void X() { ... } class B { void Y() { ... } } class C { void Y() { ... } } class A: B { void X() { ... } void Y() { C B; B.Y(); X(); } } simply typing X() would invoke A.X())?Since you know the module name, why not: <module>.X();(since B.Y() will invoke method Y() of object C)?this.B.Y() This is just like in C++: class foo { int a; public: foo(int a) { this->a = a; }; } -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Nov 08 2001
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3BEAE349.BCF30DD7 deming-os.org...And what if there's a local variable or class property with the same name as module?simply typing X() would invoke A.X())?Since you know the module name, why not: <module>.X();And what if B is not a local, but a class member? This way, this.B.Y() will still call the wrong method... What I'm in general trying to say is that I hate when there are some ambiguities. Like in C++, if I have a class Parser, I can declare objects as "Parser p". However if I have a variable called Parser, I have to use "class Parser p". The same case is here. Wouldn't it be better to provide some completely distinct way to call module globals (no ideas) and methods of base class (I propose super(class).method)? Not only it would ease the life of programmers (especially if you are working with others' code... A.B - is A a class or a variable? with super(A).B it's much clearer), but also helped the compiler as well.(since B.Y() will invoke method Y() of object C)?this.B.Y() This is just like in C++: class foo { int a; public: foo(int a) { this->a = a; }; }
Nov 09 2001
Pavel \"EvilOne\" Minayev wrote:"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3BEAE349.BCF30DD7 deming-os.org...Frankly, then you are a bad programmer :) Seriously, though, I suppose you have a point. It might be good to explicitly define syntax for such a circumstance. Some possibilities for ways to access global module data as opposed to class variables: module <moduleName>.X() module.<moduleName>.X() global.<moduleName>.X() -- The Villagers are Online! http://villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]And what if there's a local variable or class property with the same name as module?simply typing X() would invoke A.X())?Since you know the module name, why not: <module>.X();
Nov 09 2001
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3BEBCCF3.ABEBCB5 deming-os.org...Frankly, then you are a bad programmer :) Seriously, though, I supposeDefinitely. However, we shouldn't discriminate =)you have a point. It might be good to explicitly define syntax for such a circumstance. Some possibilities for ways to access global module data as opposed to class variables: module <moduleName>.X() module.<moduleName>.X() global.<moduleName>.X()I thought about it as well - since we have "this" to refer to current class, why not have something that refers to current module? "global" seems just fine to me, what about the others?
Nov 09 2001
"Pavel "EvilOne" Minayev" <evilone omen.ru> wrote in message news:9sg5vh$scq$1 digitaldaemon.com..."Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3BEAE349.BCF30DD7 deming-os.org...Hmm. It might be a good idea to use the "." as meaning "at the module level", as in: .B(); The problem, though, is the . is almost invisible. Maybe: module.B();And what if there's a local variable or class property with the same name as module?simply typing X() would invoke A.X())?Since you know the module name, why not: <module>.X();And what if B is not a local, but a class member? This way, this.B.Y() will still call the wrong method... What I'm in general trying to say is that I hate when there are some ambiguities. Like in C++, if I have a class Parser, I can declare objects as "Parser p". However if I have a variable called Parser, I have to use "class Parser p". The same case is here. Wouldn't it be better to provide some completely distinct way to call module globals (no ideas) and methods of base class (I propose super(class).method)? Not only it would ease the life of programmers (especially if you are working with others' code... A.B - is A a class or a variable? with super(A).B it's much clearer), but also helped the compiler as well.(since B.Y() will invoke method Y() of object C)?this.B.Y() This is just like in C++: class foo { int a; public: foo(int a) { this->a = a; }; }
Nov 09 2001
"Pavel "EvilOne" Minayev" <evilone omen.ru> wrote in message news:9sdigb$2715$1 digitaldaemon.com...What is the default attribute for class members (private/protected/public)?Public. I always thought that C++'s way just made for annoying extra typing when banging out quick code. A production quality class should always say it explicitly.Suppose I have the following declaration: int* x, y; Is y an int or a pointer to int?An int. I didn't break away from C on that one. I can be persuaded otherwise.Once again, suppose there's a piece of code like that: void X() { ... } class B { void Y() { ... } } class C { void Y() { ... } } class A: B { void X() { ... } void Y() { C B; B.Y(); X(); } } simply typing X() would invoke A.X())?Prefix it with the module name. Assume the module name is foo: foo.X()(since B.Y() will invoke method Y() of object C)?A.B.Y()
Nov 09 2001
"Walter" <walter digitalmars.com> wrote in message news:9sh1ca$1pn2$2 digitaldaemon.com...Yes, yes! Should we start collecting votes for a petition? =)Suppose I have the following declaration: int* x, y; Is y an int or a pointer to int?An int. I didn't break away from C on that one. I can be persuaded otherwise.I mentioned it already, but... What if class A contains variable B? Will the above code do what we expect it to?(since B.Y() will invoke method Y() of object C)?A.B.Y()
Nov 09 2001
"Pavel "EvilOne" Minayev" <evilone omen.ru> wrote in message news:9sh2a9$1qsq$1 digitaldaemon.com..."Walter" <walter digitalmars.com> wrote in message news:9sh1ca$1pn2$2 digitaldaemon.com...I'm more interested in compelling arguments (!)Yes, yes! Should we start collecting votes for a petition? =)Suppose I have the following declaration: int* x, y; Is y an int or a pointer to int?An int. I didn't break away from C on that one. I can be persuaded otherwise.A.super.Y()I mentioned it already, but... What if class A contains variable B? Will the above code do what we expect it to?(since B.Y() will invoke method Y() of object C)?A.B.Y()
Nov 09 2001
"Walter" <walter digitalmars.com> wrote in message news:9si4hs$2ved$3 digitaldaemon.com...This works if A is a direct successor of B. However, the example is simplified, but in general assume there are many other classes between A and B in the hierarchy. Now what? =)What if class A contains variable B? Will the above code do what we expect it to?A.super.Y()
Nov 09 2001
"Pavel "EvilOne" Minayev" <evilone omen.ru> wrote in message news:9sik3l$7e8$1 digitaldaemon.com..."Walter" <walter digitalmars.com> wrote in message news:9si4hs$2ved$3 digitaldaemon.com...A.super.dee.duper.B() <g>This works if A is a direct successor of B. However, the example is simplified, but in general assume there are many other classes between A and B in the hierarchy. Now what? =)What if class A contains variable B? Will the above code do what we expect it to?A.super.Y()
Nov 10 2001
Walter wrote:"Pavel "EvilOne" Minayev" <evilone omen.ru> wrote in messageHow about I call my family in New Jersey? :-) Seriously though, in the above example you would think <type> <var1>, <var2>; where var1 and var2 are both of type. Anyone who is not "used" to C's interesting interpretation of this sort of declaration (and may who are used to it) will get burned. The syntax definite isn't too clean nor too popular to be tampered with. I'd try harder to argue, but it looks like others are doing a good job of convincing you. Dan"Walter" <walter digitalmars.com> wrote in messageI'm more interested in compelling arguments (!)Yes, yes! Should we start collecting votes for a petition? =)Suppose I have the following declaration: int* x, y; Is y an int or a pointer to int?An int. I didn't break away from C on that one. I can be persuaded otherwise.
Nov 10 2001
"Walter" <walter digitalmars.com> wrote in message news:9si4hs$2ved$3 digitaldaemon.com...I'm more interested in compelling arguments (!)Suppose we have the following code: int*[]* x, y; "Old" way: x is pointer to array of pointers, y is an array of pointers. The first asterisk applies to both, the second is applied only to x. Not only it's weird, but just try to define a _clear_ rule (say, for the specification) that strictly defines meaning of asterisk. New way: both are pointers to array of pointers. Anything that's on the left is part of the type and is applied to all variables on the line, no special cases and exceptions. I vote for the new one...
Nov 11 2001
"Pavel "EvilOne" Minayev" <evilone omen.ru> wrote in news:9slgrh$241h$1 digitaldaemon.com..."Walter" <walter digitalmars.com> wrote in message news:9si4hs$2ved$3 digitaldaemon.com...PLEASE don't do that! Don't change the meaning while keeping the sintax! I think the ',' in declarations is useless, and error prone, so it's best to remove it. Write: int*[]* x; int*[]* y; And it works in C, C++, and D. CiaoI'm more interested in compelling arguments (!)Suppose we have the following code: int*[]* x, y; "Old" way: x is pointer to array of pointers, y is an array of pointers. The first asterisk applies to both, the second is applied only to x. Not only it's weird, but just try to define a _clear_ rule (say, for the specification) that strictly defines meaning of asterisk. New way: both are pointers to array of pointers. Anything that's on the left is part of the type and is applied to all variables on the line, no special cases and exceptions. I vote for the new one...
Nov 12 2001
"Roberto Mariottini" <rmariottini lycosmail.com> wrote in message news:9so8hl$rln$1 digitaldaemon.com...I think the ',' in declarations is useless, and error prone, so it's besttoremove it.Never ever!Write: int*[]* x; int*[]* y; And it works in C, C++, and D.First, it won't work in C/C++ since they don't support dynamic arrays. And if you are concerned about compatibility, you can write this way of course, but why forbid the other ways?
Nov 12 2001
me too Roland Pavel \"EvilOne\" Minayev a écrit :"Walter" <walter digitalmars.com> wrote in message news:9si4hs$2ved$3 digitaldaemon.com...I'm more interested in compelling arguments (!)Suppose we have the following code: int*[]* x, y; "Old" way: x is pointer to array of pointers, y is an array of pointers. The first asterisk applies to both, the second is applied only to x. Not only it's weird, but just try to define a _clear_ rule (say, for the specification) that strictly defines meaning of asterisk. New way: both are pointers to array of pointers. Anything that's on the left is part of the type and is applied to all variables on the line, no special cases and exceptions. I vote for the new one...
Nov 12 2001
"Pavel "EvilOne" Minayev" <evilone omen.ru> wrote in message news:9slgrh$241h$1 digitaldaemon.com..."Walter" <walter digitalmars.com> wrote in message news:9si4hs$2ved$3 digitaldaemon.com...I think you're right.I'm more interested in compelling arguments (!)Suppose we have the following code: int*[]* x, y; "Old" way: x is pointer to array of pointers, y is an array of pointers. The first asterisk applies to both, the second is applied only to x. Not only it's weird, but just try to define a _clear_ rule (say, for the specification) that strictly defines meaning of asterisk. New way: both are pointers to array of pointers. Anything that's on the left is part of the type and is applied to all variables on the line, no special cases and exceptions. I vote for the new one...
Nov 29 2001
Walter wrote:"Pavel "EvilOne" Minayev" <evilone omen.ru> wrote in message news:9slgrh$241h$1 digitaldaemon.com...Seconded! You know, it seems like about half of the bugs mentioned in those PC-Lint ads descend from just this issue. Let's kill it dead in D! However, I'd like to make it even more stringent: "A single declaration can create variables of only a single type." Let's eliminate all the cousins of the above, such as: int*[]* x, y, *z; This should be an error! The "correct" form should require z to be on a separate line. Pretty please? -BobC"Walter" <walter digitalmars.com> wrote in message news:9si4hs$2ved$3 digitaldaemon.com...I think you're right.I'm more interested in compelling arguments (!)Suppose we have the following code: int*[]* x, y; "Old" way: x is pointer to array of pointers, y is an array of pointers. The first asterisk applies to both, the second is applied only to x. Not only it's weird, but just try to define a _clear_ rule (say, for the specification) that strictly defines meaning of asterisk. New way: both are pointers to array of pointers. Anything that's on the left is part of the type and is applied to all variables on the line, no special cases and exceptions. I vote for the new one...
Nov 29 2001
On Fri, 30 Nov 2001 04:31:11 +0000, Robert W. Cunningham wrote:Let's eliminate all the cousins of the above, such as: int*[]* x, y, *z; This should be an error! The "correct" form should require z to be on a separate line.Yes, I agree with this, for several reasons. It simplifies the language and makes reading the code easier. I think there would be less confusion with the C syntax. And you can rewrite the above declaration as: int*[] *x, y, *z; This is admittedly foolish, but certainly not implausible. It looks like x and z are of the same type when actually x and y are. (Unless you count the space as a delimiter, which isn't nice.)
Nov 30 2001
Yes: pointers are types. so the '*' must be after the pointed type, NOT before the pointer name: int* pointer; <- correct int *pointer; <- NOT correct so int* p1,p2,p3; <- correct, all are pointers int *p1,p2,p3; <- NOT correct Rolandint*[]* x, y, *z; This should be an error! The "correct" form should require z to be on a separate line.
Nov 30 2001
Roland wrote:int* p1,p2,p3; <- correct, all are pointers int *p1,p2,p3; <- NOT correctAre you stating that it currently is a syntax error, or that you think it should be? Certainly, the latter syntax is confusing...but I think that it is legal currently. I would very much want to encourage the former syntax...but I would hate to make D more limiting than C when it comes to parsing the tokens. A warning, perhaps? -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Nov 30 2001
Russ Lewis a écrit :Roland wrote:Should be. With the new style for pointer declaration there is no more use to let the '*' front of the data name instead of back the pointed type. So pointer declaration syntax is standard now: Type instance1[instance2,..]; If we considere for example 'int*' as a type. Rolandint* p1,p2,p3; <- correct, all are pointers int *p1,p2,p3; <- NOT correctAre you stating that it currently is a syntax error, or that you think it should be?
Nov 29 2001
The key issue to me here is the parsing of tokens. As I understand C parsing, whitespace is only used to delimit tokens which cannot be otherwise differentiated, most notably strings of characters that make up keywords and identifiers. Where the differentiation is clear by the character sequence, whitespace is not needed. What I mean is that the following lines are all viewed as identical to the C compiler: int* ptr; int *ptr; int*ptr; Each is parsed into four tokens: 'int' '*' 'ptr' ';' In order to do what you suggest, we must put artificial and very un-C-like restrictions on the parser. IMHO, that is very undesirable as is starts us down a path of special case rules and a buggy parser. The syntax you suggest is good...I will use it in my D programs. But I don't think that we can require it. -- The Villagers are Online! http://villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Nov 30 2001
Russ Lewis a écrit :The key issue to me here is the parsing of tokens. As I understand C parsing, whitespace is only used to delimit tokens which cannot be otherwise differentiated, most notably strings of characters that make up keywords and identifiers. Where the differentiation is clear by the character sequence, whitespace is not needed. What I mean is that the following lines are all viewed as identical to the C compiler: int* ptr; int *ptr; int*ptr; Each is parsed into four tokens: 'int' '*' 'ptr' ';' In order to do what you suggest, we must put artificial and very un-C-like restrictions on the parser. IMHO, that is very undesirable as is starts us down a path of special case rules and a buggy parser. The syntax you suggest is good...I will use it in my D programs. But I don't think that we can require it.I thought whitespaces were separators un C. I agree the goal is not to add special cases but to supress them. What i suggested is to standardize the fact that all type information must be at the left of the instance name. In the same spirit as arrays declaration: int[] array_of_int_instance; //D style, type is declared completely before instance name instead of int array_of_int_instance[]; //C style, from left to right: it is a 'int' named 'array_of_int_instance' but in fact it is an array: '[]' And standardize the fact that all instances declared at the right of the type declaration, separated by ',' , should be of this type: int* p1,p2; //D style: all type 'int*' Instead of; int *p1,p2; // C style: mixed types. p1 is a 'int*' , p2 is a int Pavel \"EvilOne\" Minayev a écrit :Suppose we have the following code: int*[]* x, y; "Old" way: x is pointer to array of pointers, y is an array of pointers. The first asterisk applies to both, the second is applied only to x. Not only it's weird, but just try to define a _clear_ rule (say, for the specification) that strictly defines meaning of asterisk. New way: both are pointers to array of pointers. Anything that's on the left is part of the type and is applied to all variables on the line, no special cases and exceptions. I vote for the new one...Me too Roland
Dec 01 2001
I agree with the sentiment. It will just need comments from some more knowledge able people (are you lurking, Walter?) about whether it is technically feasible without specail cases in the parser. -- The Villagers are Online! http://villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Dec 01 2001
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3C08E404.67B8A193 deming-os.org...I agree with the sentiment. It will just need comments from some moreknowledge ablepeople (are you lurking, Walter?) about whether it is technically feasiblewithout specailcases in the parser.I have run into some problems with it. Specifically, pointers to functions. C: int (*fp)(args); // ugly, but servicable D: int (*)(args) fp; // ?? int (args)* fp; // ?? arrgh
Dec 01 2001
"Walter" <walter digitalmars.com> wrote in message news:9ubqoj$1lh7$1 digitaldaemon.com...I have run into some problems with it. Specifically, pointers tofunctions.C: int (*fp)(args); // ugly, but servicable D: int (*)(args) fp; // ?? int (args)* fp; // ?? arrghSolution: int(args) fp; No need for * here anyhow, since we can only have pointers to functions, not function variables by themselves.
Dec 02 2001
And for pointers to methods, I'd suggest the following: int.(args) mp;
Dec 02 2001
"Pavel Minayev" <evilone omen.ru> wrote in message news:9ucq38$2o5m$1 digitaldaemon.com...And for pointers to methods, I'd suggest the following: int.(args) mp;I'm trying to avoid pointers to members <g>.
Dec 02 2001
"Walter" <walter digitalmars.com> wrote in message news:9uctpk$2rvp$3 digitaldaemon.com..."Pavel Minayev" <evilone omen.ru> wrote in message news:9ucq38$2o5m$1 digitaldaemon.com...A question then. Since D doesn't have macroses, it would be hard to define a simple syntax for message maps. Pointers to members are not supported. If I want to write a GUI library for D, what other ways could I use then? WndProc and switch() (aka back to the WinAPI days)? nah, totally ditches the idea... anything else? Just to make this all clearer, a code that could be part of a GUI library: // =================================================== // using pointers to methods, if they were implemented class Button { void.() OnClick int WndProc(uint uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_LBUTTONDOWN) OnClick() } } class MyForm { Button cmdOk; this() { cmdOk.OnClick = cmdOk_Click; } void cmdOk_Click() { // do something useful... } } // ============================================= // using map tables, if there were macroses in D class MyForm { BEGIN_MESSAGE_MAP(MyForm) ON_NOTIFY(IDC_CMDOK, BN_CLICKED, cmdOk_Click) END_MESSAGE_MAP() void cmdOk_Click() { // do something useful... } } // ======================================== // using if() or switch(), already possible class MyForm { int WndProc(uint uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_COMMAND && hiword(wParam) == IDC_CMDOK) cmdOk_Click(); } void cmdOk_Click() { // do something useful... } }And for pointers to methods, I'd suggest the following: int.(args) mp;I'm trying to avoid pointers to members <g>.
Dec 02 2001
"Pavel Minayev" <evilone omen.ru> wrote in message news:9ucvsu$2u60$1 digitaldaemon.com...Since D doesn't have macroses, it would be hard to define a simple syntax for message maps. Pointers to members are not supported. If I want to write a GUI library for D, what other ways could I use then? WndProc and switch() (aka back to the WinAPI days)? nah, totally ditches the idea... anything else?What you could do is create an array of function pointers, indexed by the message number. A default one is provided by the gui library. You could write an associative array that contains just the messages you want to dispatch on. So, you test your local associative array, if it's there, dispatch. Otherwise, use the default array, and dispatch to that one. Member function pointers are not necessary, just use a static member function.
Dec 03 2001
Been there, done that, in Pascal and C. Interfacing to Windows User. That just brings us back around to how to ease the passing of control back into a real actual object, the transmission of the this pointer has to be done somehow, and that just makes the programmer write forwarding functions with an extra object pointer parameter. It can be argued that anything beyond the goto, test, and addition and negation is not "necessary" because we can build it ourselves from more primitive tools. I don't want to have to build language tools to be able to get basic work done. You'd think that a language designed today would function to make our lives easier. I guess some kind of a member function pointer bundled with a this pointer would be a good enough replacement, if that is any less problematic. Callbacks to objects is the main goal here I think. Sean "Walter" <walter digitalmars.com> wrote in message news:9ufg0t$2i1n$1 digitaldaemon.com..."Pavel Minayev" <evilone omen.ru> wrote in message news:9ucvsu$2u60$1 digitaldaemon.com...Since D doesn't have macroses, it would be hard to define a simple syntax for message maps. Pointers to members are not supported. If I want to write a GUI library for D, what other ways could I use then? WndProc and switch() (aka back to the WinAPI days)? nah, totally ditches the idea... anything else?What you could do is create an array of function pointers, indexed by the message number. A default one is provided by the gui library. You could write an associative array that contains just the messages you want to dispatch on. So, you test your local associative array, if it's there, dispatch. Otherwise, use the default array, and dispatch to that one. Member function pointers are not necessary, just use a static member function.
Dec 03 2001
"Sean L. Palmer" <spalmer iname.com> wrote in message news:9ufhqn$2jsd$1 digitaldaemon.com...Been there, done that, in Pascal and C. Interfacing to Windows User.Thatjust brings us back around to how to ease the passing of control back intoareal actual object, the transmission of the this pointer has to be done somehow, and that just makes the programmer write forwarding functionswithan extra object pointer parameter.Exactly! Suppose we have an MDI application. In this case, you'd probably want each event to be handled by the appropriate object, associated with the child window, not by a static function shared by all objects. This is just an additional headache for the user of the library, since there are no macroses to simplify it.It can be argued that anything beyond the goto, test, and addition and negation is not "necessary" because we can build it ourselves from more primitive tools. I don't want to have to build language tools to be abletoget basic work done. You'd think that a language designed today would function to make our lives easier. I guess some kind of a member function pointer bundled with a this pointer would be a good enough replacement, if that is any less problematic. Callbacks to objects is the main goal hereIthink.Yes. Since window is represented by an object of a specific class, and there can be several objects of that class, each window should handle its events separately, without additional layers (that have to be manually coded by the end-user!) like static functions. I can't really understand what's bad with the idea? What are the arguments against having it in D?
Dec 03 2001
"Pavel Minayev" <evilone omen.ru> wrote in message news:9ug6ai$815$1 digitaldaemon.com...I can't really understand what's bad with the idea? What are the arguments against having it in D?Member function pointers are confusing (to me, anyway), and there's some significant complexity involved with getting them implemented right.
Dec 03 2001
"Walter" <walter digitalmars.com> wrote in message news:9uhjh9$1fhs$5 digitaldaemon.com..."Pavel Minayev" <evilone omen.ru> wrote in message news:9ug6ai$815$1 digitaldaemon.com...I agree that _C++_ method pointers are confusing. But what's wrong with Delphi-like ones that I propose? In fact, what they allow is to treat methods just like you treat global functions when dealing with callbacks. What's confusing in it?I can't really understand what's bad with the idea? What are the arguments against having it in D?Member function pointers are confusing (to me, anyway), and there's somesignificant complexity involved with getting them implemented right.Not sure what it can be... could you give an example? BTW due to the fact I needed them badly and C++ don't have them, I've implemented method pointers using templated class and some hacks... and the code was quite small.
Dec 03 2001
"Pavel Minayev" <evilone omen.ru> wrote in message news:9uhsjq$1lb3$1 digitaldaemon.com...You have to generate things like thunks. Ugh.significant complexity involved with getting them implemented right.Not sure what it can be... could you give an example?BTW due to the fact I needed them badly and C++ don't have them, I've implemented method pointers using templated class and some hacks... and the code was quite small.But C++ does have pointers to member functions.
Dec 04 2001
"Walter" <walter digitalmars.com> wrote in message news:9ui1i8$1q67$1 digitaldaemon.com...But C++ does have pointers to member functions.I've probably explained the thing badly. Yes, C++ has pointers to methods. However, they point to method of some _class_ rather than to method of some _object_. These are very different things. Of course, you can store pointer to object elsewhere, but not only it looks clumsy from the POV of end-user, there is also a stupid limitation of method belonging to exact given class, not even its child classes - and no workaround for the problem. Such pointers are completely useless in context of GUI library: void (CForm::*OnClick)(int x, y); ... class CMyForm: public CForm { public: void Click(int x, y); } MyForm; OnClick = CMyForm::Click; // oops, won't work! On other hand, Delphi pointers do point to method of one concrete object, and they absolutely don't care of its class - they simply treat method as a function which has a context "this" pointer associated with it: var OnClick: procedure(x,y: integer) of object; ... type TMyForm = class(TForm); public procedure Click(x,y: integer); end; var MyForm: TMyForm; begin OnClick := MyForm.Click; // everything's fine end;
Dec 04 2001
Pavel Minayev a écrit :A question then. Since D doesn't have macroses, it would be hard to define a simple syntax for message maps. Pointers to members are not supported. If I want to write a GUI library for D, what other ways could I use then? WndProc and switch() (aka back to the WinAPI days)? nah, totally ditches the idea... anything else? Just to make this all clearer, a code that could be part of a GUI library: // =================================================== // using pointers to methods, if they were implemented class Button { void.() OnClick int WndProc(uint uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_LBUTTONDOWN) OnClick() } } class MyForm { Button cmdOk; this() { cmdOk.OnClick = cmdOk_Click; } void cmdOk_Click() { // do something useful... } }Yes, this is a common problem having an object that trap events or calls, and just dispatch them to an other object. It can be done with a pointer function as you sugest or in theory with a pointer to the destination object: class CmdOkButton { MyForm* dest; this(MyForm* frm): dest(frm) { } int WndProc(uint uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_LBUTTONDOWN) dest.cmdOk_Click() } } In practice it's boring: create a class for all message, and writing functions that just transfer the call to an other object. I suggest (i know, it's easier to sugest than to implement): class Button { void.OnClick() //note OnClick is a normal member function int WndProc(uint uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_LBUTTONDOWN) OnClick() } } class MyForm { Button cmdOk; this() { cmdOk.OnClick = cmdOk_Click; //yes !, see below } void cmdOk_Click() { // do something useful... } } Button::OnClick is a normal (virtual) function. cmdOk.OnClick = cmdOk_Click writes in cmdOk Virtual Table !!?? Yes. It's ok if cmdOk have its _own_ virtual table. Overwriting a member function of a class, should instruct the compiler that this class is what can be called a "Transfer Class". Transfer Classes properties: - All objects of this type have ther _own_ Virtual Table duplicated from the Type's one, - they also have a table for 'this' pointer translation so that for example cmdOk_Click function recieve a 'this' pointer pointing on the MyForm object, NOT on the MyForm object :: cmdOk. Advantages: - no more pointers to member, - its fast Inconvenients: - memory consumption (cheap now), - is it in D spirit ? If this not too complicate to implement, i think that is the easiest way to do the job, and after all, at low level, virtual functions are functions pointers isn't it ? Roland
Dec 11 2001
"Roland" <rv ronetech.com> wrote in message news:3C16714A.FB186A1F ronetech.com...Button::OnClick is a normal (virtual) function. cmdOk.OnClick = cmdOk_Click writes in cmdOk Virtual Table !!?? Yes. It's ok if cmdOk have its _own_ virtual table. Overwriting a member function of a class, should instruct the compiler that this class is what can be called a "Transfer Class".The problem here is that it's not very easy to find out if some _object_ of that class gets its vtable changed: Control cmdOk; // note: not a Button! cmdOk = new Button; cmdOk.OnClick = cmdOk_Click;Transfer Classes properties: - All objects of this type have ther _own_ Virtual Table duplicated from the Type's one, - they also have a table for 'this' pointer translation so that for example cmdOk_Click function recieve a 'this' pointer pointing on the MyForm object, NOT on the MyForm object :: cmdOk.I don't see the actual difference between this and pointers to methods. Both here and there, you store pointer to object together with pointer to function, only in your case they're separated into two tables. Making vtables dynamic (Delphi term, vtables are per object rather than per class) uses much more memory especially with complex class hierarchy while not providing any advantages (it's not faster, and - IMHO - not easier to implement).to do the job, and after all, at low level, virtual functions are functions pointers isn't it ?Yes but we were talking about pointers to methods, right? And these are different...
Dec 12 2001
Pavel Minayev a écrit :The problem here is that it's not very easy to find out if some _object_ of that class gets its vtable changed: Control cmdOk; // note: not a Button! cmdOk = new Button; cmdOk.OnClick = cmdOk_Click;object must switch from static to dynamic virtual table at run timeI don't see the actual difference between this and pointers to methods. Both here and there, you store pointer to object together with pointer to function, only in your case they're separated into two tables. Making vtables dynamic (Delphi term, vtables are per object rather than per class) uses much more memory especially with complex class hierarchy while not providing any advantages (it's not faster, and - IMHO - not easier to implement).Franckly, if i understand well the concept, i had to remind pointer to methodes syntax in C++, as i never used them. First impression: not a very nice syntax, may be usefull, i should use them. But they had already been rejected for D. I would try to suggest a replacement, something clean, before the boss come. class Button { void.OnClick() { <default action> } int WndProc(uint uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_LBUTTONDOWN) OnClick() } } class MyForm { Button cmdOk; this() { cmdOk.OnClick = cmdOk_Click; //<-------- here } void cmdOk_Click() { // do something useful... } } MyForm myform; The goal is: - a click event on myform.cmdOk calls myform.cmdOk_Click, - of course, in cmdOk_Click, 'this' points on myform, NOT on myform.cmdOk I sugest for that, just write: cmdOk.OnClick = cmdOk_Click I think this syntax is simple and that can replace pointer to member functions. But: - it must not be too complicate to implement, - it must not slow down normal virtual function call. //------------------------------------------------------ Inthe way for implementation: A little deeper inside the machine: Lets translate from D to C to show how virtuals are: //- - - - - - - - - //Button struct Button_VT { //virtual table of Button type, created by compliler in C++/D void *OnClick(); }; struct Button { Button_VT* vt; //hidden pointer to virtual table, created and initialized by compliler in C++/D }; void virtual_Button_OnClick(Button* this) { //virtual function call mechanism (inlined) this->vt->OnClick(this); } void.Button_OnClick(Button* this) { <default action> } //- - - - - - - - - //MyForm struct MyForm_VT { //virtual table of MyForm type, created by compliler in C++/D void *cmdOk_Click(); }; struct MyForm { MyForm_VT* vt; //hidden pointer to virtual table, created and initialized by compliler in C++/D Button cmdOk; } void virtual_MyForm_cmdOk_Click(MyForm* this) { //virtual function call mechanism (inlined) this->vt->cmdOk_Click(this); } void MyForm_cmdOk_Click(MyForm* this) { do something useful... } //- - - - - - - - - //declare objects: static Button_VT button_VT; static MyForm_VT myform_VT; MyForm myform; //click event on myform.cmdOk: same as a call to: virtual_Button_OnClick(&myform.cmdOk); //------------------------------- Now lets translate from D to C "myform.cmdOk.OnClick = myform.cmdOk_Click" statement: 1° in D: "myform.cmdOk.OnClick = myform.cmdOk_Click" statement: => myform.cmdOk.vt->OnClick = MyForm_cmdOk_Click not good: - all object of class MyForm will be affected - in MyForm_cmdOk_Click, 'this' will point on myform.cmdOk instead of myform. 2° in D: "myform.cmdOk.OnClick = myform.cmdOk_Click" statement: => allocate a new Button_VT: new_Button_VT => copy button_VT to new_Button_VT => set new_Button_VT.OnClick = MyForm_cmdOk_Click => set myform.cmdOk.vt = new_Button_VT solve the first problem: myform.cmdOk switches from a static VT to a dynamic VT. the other one is a little more complicate. 3° lets create a new struct: struct Button_VT2: Button_VT { void* onclickthis; Button_VT ivt; }; and a new function: void.Button_VT2_OnClick(Button* buttonp) { ((Button_VT2*)buttonp->vt)->ivt->OnClick(((Button_VT2*)buttonp->vt)->onclickthis); } now: in D: "myform.cmdOk.OnClick = myform.cmdOk_Click" statement: => allocate a new Button_VT2: new_Button_VT2 => copy button_VT to new_Button_VT2.ivt => set new_Button_VT2.ivt.OnClick = MyForm_cmdOk_Click => set new_Button_VT2.OnClick = Button_VT2_OnClick => set new_Button_VT2.onclickthis = &myform => set myform.cmdOk.vt = new_Button_VT2 okay, it work like this: event: virtual_Button_OnClick(&myform.cmdOk) => myform.cmdOk.vt->OnClick(&myform.cmdOk) => Button_VT2_OnClick(&myform.cmdOk) => ((Button_VT2*)myform.cmdOk.vt)->ivt->OnClick(((Button_VT2*)myform.cmdOk.vt)->destobject) => MyForm_cmdOk_Click(&myform) done a little slow but acceptable Everything seems too nice. There must be something wrong there. but what ? Roland
Dec 22 2001
"NancyEtRoland" <nancyetroland free.fr> wrote in message news:3C251BB2.F4053844 free.fr...I sugest for that, just write: cmdOk.OnClick = cmdOk_Click I think this syntax is simple and that can replace pointer to member functions.Exactly what I proposed.Everything seems too nice. There must be something wrong there. but what ?IMHO there's no need to mess with virtuals at all. In other words, once you bind the function to the event slot, you bind the _concrete function_ by its pointer-to-code, bypassing vtable. As the result, you don't have to mess with all the vtable stuff - just store the pointer to object and pointer to function itself, 8 bytes total, and call them simply. In C, that'd look like: struct event { void* object; void (*method)(void*, ...); } event; event.method(event.object, arg1, arg2, arg3);
Dec 23 2001
Pavel Minayev a écrit :IMHO there's no need to mess with virtuals at all. In other words, once you bind the function to the event slot, you bind the _concrete function_ by its pointer-to-code, bypassing vtable. As the result, you don't have to mess with all the vtable stuff - just store the pointer to object and pointer to function itself, 8 bytes total, and call them simply. In C, that'd look like: struct event { void* object; void (*method)(void*, ...); } event; event.method(event.object, arg1, arg2, arg3);Putting those pointers to vtable is in fact exactely the same (even if it *looks* more messy) but this way there is no need for "pointers to member function" type. Roland
Dec 26 2001
Pavel makes a critical point here that must be noted. Callbacks, very often should not be targeted at the objects that created them. That is, you note that the Button object is what "receives" the OnClick message...but it is a function in MyForm that must process it. If we go the traditional C++ route (but don't use macros) then we are left with this terrible code: //declared by the API class Button; // user code class MyForm { void cmdOk_Click(); class MyForm_Button : public Button { private: MyForm *form; public: MyForm_Button(MyForm *form) { this->form = form; }; public: void OnClick() { return form->cmdOk_Click(); }; }; MyForm_Button okButton; ... }; Then the constructor for MyForm must pass a pointer to itself to the constructor for okButton, and so on. It gets worse. The point here is that, in old C++, you can't easily declare an object that delegates its callbacks to the encapsulating object. It would be a Good Thing if D allowed this. A Side Note: It's possible to do more flexible callbacks with C++ using templates; you force the compiler to, under the covers, create a wrapper function that calls the right member function of the right class. But it's a -- The Villagers are Online! http://villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Dec 25 2001
Russ Lewis a écrit :Pavel makes a critical point here that must be noted. Callbacks, very often should not be targeted at the objects that created them. That is, you note that the Button object is what "receives" the OnClick message...but it is a function in MyForm that must process it. If we go the traditional C++ route (but don't use macros) then we are left with this terrible code: //declared by the API class Button; // user code class MyForm { void cmdOk_Click(); class MyForm_Button : public Button { private: MyForm *form; public: MyForm_Button(MyForm *form) { this->form = form; }; public: void OnClick() { return form->cmdOk_Click(); }; }; MyForm_Button okButton; ... };That is some kind of code we all do and i would apreciate a compiler do for me: it's boringIt's possible to do more flexible callbacks with C++ using templates; you force the compiler to, under the covers, create a wrapper function that calls the right member function of the right class. But it's aI tried too: not nicer. Next time i try to do it with pointers to methode.. in C++. Roland
Dec 26 2001
NancyEtRoland wrote:I tried too: not nicer. Next time i try to do it with pointers to methode.. in C++.I have implemented the following in C++: struct Handler { ... }; struct ArgType { ... }; Handler MakeHandler(ArgType (*func)()); Handler MakeHandler(ArgType (*func)(ArgType)); template <class X> Handler MakeHandler(ArgType (X::*func)()); template <class X> Handler MakeHandler(ArgType (X::*func)(ArgType)); Handler overloads operator(), which takes a single ArgType value and returns an ArgType. The point here is that, using templates, I can create an arbitrary structure (kind of like a generic pointer-to-function or pointer-to-member-function) that you can then use like a function pointer. Unfortunately, my company hasn't (yet) released the source code to open source, though I'm hoping they will. Fortunately, I developed this based on stuff I found freely on the web. -- The Villagers are Online! http://villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Dec 26 2001
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3C2A5F43.C58C4EEB deming-os.org...I have implemented the following in C++: struct Handler { ... }; struct ArgType { ... }; Handler MakeHandler(ArgType (*func)()); Handler MakeHandler(ArgType (*func)(ArgType)); template <class X> Handler MakeHandler(ArgType (X::*func)()); template <class X> Handler MakeHandler(ArgType (X::*func)(ArgType)); Handler overloads operator(), which takes a single ArgType value andreturns anArgType. The point here is that, using templates, I can create anarbitrarystructure (kind of like a generic pointer-to-function or pointer-to-member-function) that you can then use like a function pointer.I've came to the same solution; however, I couldn't make Visual C++ to work with that sort of templates. Borland C++, on other hand, did the job just fine. So I've made it more general (and less typesafe): template <class X> Handler MakeHandler(X func); IMO, all these efforts are a fine example of why having such a construct built-in into language would be really great!
Dec 26 2001
My code has to be portable between gcc on Linux and MSVC on Windows. The simple design, which works on gcc, failed on MSVC because the compiler was too simpleminded to handle it. But it can be done...I hope someday to post the MSVC solution. :( As you say, it would be a great thing to have in the language. I even posted a C-compatible solution for member function pointers in a previous post called "Member Function Pointers" (8/20/01) -- The Villagers are Online! http://villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Dec 26 2001
I am not sure why you would want to avoid pointers to member functions... they sure can be useful sometimes. Declaration syntax could be: class Foo { void Fn1(int a); void Fn2(int a); } void Foo:(int) memfuncptr = Foo.Fn1. Calling syntax could then be: object.memfuncptr:(args); Which kinda matches the declaration syntax I proposed. Ok, so I can't think of a decent syntax either. ;( But I'd still like to see them included in D. Sean "Walter" <walter digitalmars.com> wrote in message news:9uctpk$2rvp$3 digitaldaemon.com...I'm trying to avoid pointers to members <g>.
Dec 02 2001
"Sean L. Palmer" <spalmer iname.com> wrote in message news:9ud1c0$2vqm$1 digitaldaemon.com...I am not sure why you would want to avoid pointers to member functions... they sure can be useful sometimes. Declaration syntax could be: class Foo { void Fn1(int a); void Fn2(int a); } void Foo:(int) memfuncptr = Foo.Fn1. Calling syntax could then be: object.memfuncptr:(args); Which kinda matches the declaration syntax I proposed. Ok, so I can't think of a decent syntax either. ;( But I'd still like to see them included in D.Yeah, syntax is a question. Still I'd like to see them in D, especially if they are able to hold pointer to object together with pointer to method, as I've stated before =)
Dec 02 2001
"Sean L. Palmer" wrote:I am not sure why you would want to avoid pointers to member functions... they sure can be useful sometimes.So can operator overloading. So can the preprocesser. So can multiple inheritance. So can templates. The better question might be, what (if anything) will be in D to replace the functionality? Dan
Dec 02 2001
Pavel Minayev wrote:... And for pointers to methods, I'd suggest the following: int.(args) mp; ...I assume that in a real example the args would be spelled out? How do you feel one should list a method that required a method argument? int.(.op(int.val1, float.val2) int.val1, float.val2) theFunc; Perhaps?
Dec 03 2001
"Charles Hixson" <charleshixsn earthlink.net> wrote in message news:3C0BF296.6010808 earthlink.net...I assume that in a real example the args would be spelled out? How do you feel one should list a method that required a method argument? int.(.op(int.val1, float.val2) int.val1, float.val2) theFunc;int.(int.(int) method1, void.(float, float), char[]) theFunc; Dot should always go to the right. Or to the left - whichever you prefer =)
Dec 03 2001
Walter wrote:C: int (*fp)(args); // ugly, but servicable D: int (*)(args) fp; // ?? int (args)* fp; // ?? arrghA couple of other brainstorms: int (*function)(args) fp1,fp2; // requires new keyword 'function' int func-ptr(args) fp1,fp2; // requires new keyword 'func-ptr' int (* fp1,fp2)(args); // really ugly :( -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Dec 03 2001
Russ Lewis a écrit :Walter wrote:int function(args)* fp1,fp2; // requires new keyword 'function' //pointed type is defined before '*' RolandC: int (*fp)(args); // ugly, but servicable D: int (*)(args) fp; // ?? int (args)* fp; // ?? arrghA couple of other brainstorms: int (*function)(args) fp1,fp2; // requires new keyword 'function' int func-ptr(args) fp1,fp2; // requires new keyword 'func-ptr' int (* fp1,fp2)(args); // really ugly :(
Dec 04 2001
"Robert W. Cunningham" <rwc_2001 yahoo.com> wrote in message news:3C070B8E.984C6418 yahoo.com...Let's eliminate all the cousins of the above, such as: int*[]* x, y, *z; This should be an error! The "correct" form should require z to be on a separate line.Yeah, that should be an error. -Walter
Nov 30 2001
Persuade, persuade, persuade, persuade. Is that enough, or do we need more? -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]Suppose I have the following declaration: int* x, y; Is y an int or a pointer to int?An int. I didn't break away from C on that one. I can be persuaded otherwise.
Nov 09 2001
Walter wrote:"Pavel "EvilOne" Minayev" <evilone omen.ru> wrote in message news:9sdigb$2715$1 digitaldaemon.com...I'd personally lobby for the default attribute be "compilererror". That's just me though. _RWhat is the default attribute for class members (private/protected/public)?Public. I always thought that C++'s way just made for annoying extra typing when banging out quick code. A production quality class should always say it explicitly.
Nov 09 2001
"Walter" <walter digitalmars.com> wrote in message news:9sh1ca$1pn2$2 digitaldaemon.com...typingWhat is the default attribute for class members (private/protected/public)?Public. I always thought that C++'s way just made for annoying extrawhen banging out quick code. A production quality class should always sayitexplicitly.Agreed. I suppose inheritance is also by default public?Since you're changing the type specifiers anyway... may as well fix this legacy crap. I can't tell you how many times this has burned me. If someone wants two different types of variables, s/he can make two separate declarations. This goes hand-in-hand with the idea to keep the type specifier all together in one place, parseable right to left. If you start letting people put part of the type off somewhere else, the problem comes back such that type specifiers aren't complete, and people get confused.Suppose I have the following declaration: int* x, y; Is y an int or a pointer to int?An int. I didn't break away from C on that one. I can be persuaded otherwise.Prefix it with the module name. Assume the module name is foo: foo.X()What if someone made a local variable or member function named foo also? Yes they're bad... maybe we could allow some syntax like this: ().X() or static.X() Some way to unambiguously get to the "global" scope (current module). Maybe you could import foo; again, right there in the function, which overrides the local foo.
Nov 09 2001
"Sean L. Palmer" <spalmer iname.com> wrote in message news:9sh8ic$233l$1 digitaldaemon.com..."Walter" <walter digitalmars.com> wrote in message news:9sh1ca$1pn2$2 digitaldaemon.com...saytypingWhat is the default attribute for class members (private/protected/public)?Public. I always thought that C++'s way just made for annoying extrawhen banging out quick code. A production quality class should alwaysitYes.explicitly.Agreed. I suppose inheritance is also by default public?startSince you're changing the type specifiers anyway... may as well fix this legacy crap. I can't tell you how many times this has burned me. If someone wants two different types of variables, s/he can make two separate declarations. This goes hand-in-hand with the idea to keep the type specifier all together in one place, parseable right to left. If youSuppose I have the following declaration: int* x, y; Is y an int or a pointer to int?An int. I didn't break away from C on that one. I can be persuaded otherwise.letting people put part of the type off somewhere else, the problem comes back such that type specifiers aren't complete, and people get confused.I think you're right.What if someone made a local variable or member function named foo also?Don't do that. It doesn't seem to be a significant problem in C.
Nov 09 2001
I would argue in favor of breaking with tradition on the 'int *x, y;' question. Try listing out some arguments on each side: For breaking with tradition: ---------------------------- 1) The C way is frequently misunderstood by beginners. 2) The C way often leads to bugs (even if they are usually caught by the compiler, they are still bugs). 3) The C way associates the * with the variable rather than the type; does anyone really want to be able to have 'int *x, y, *z;'? 4) The C way requires more typing, admittedly only one more character per variable, but more is more. 5) If one is reading C code and sees 'int *x, y;', there is always the nagging feeling that the person who wrote it made a mistake. 6) In writing actual code, I sometimes want to declare two pointer variables; I almost never want to declare both a pointer and a non-pointer. For staying with tradition: --------------------------- 1) Compatibility. 2) It turns out that there is a case where both a pointer and a non-pointer are declared simultaneously that occurs fairly often, and that is typedef. For example typedef struct Foo_tag *FooPointer, Foo; (Substitute Hungarian notation for 'FooPointer' if that is your preference.) So the old C way is used sometimes in ways that are at least semi-reasonable. On balance the arguments for breaking with tradition seem stronger than those for staying with tradition. Or are there some important arguments that are missing? "Walter" <walter digitalmars.com> writes:"Pavel "EvilOne" Minayev" <evilone omen.ru> wrote in messageSuppose I have the following declaration: int* x, y; Is y an int or a pointer to int?An int. I didn't break away from C on that one. I can be persuaded otherwise.
Nov 10 2001
Walter wrote:"Pavel "EvilOne" Minayev" <evilone omen.ru> wrote in message news:9sdigb$2715$1 digitaldaemon.com...I say private would be better for quality code. Argueing for this is quite simple, if there is nothing standing there you can suppose that programmer simply forgot about the access attribute. If he actually ment private, but public is default, he gets no compiler errors/warnings. If he actually ment public, but private is default, the compiler will point him on the failure. - Axel -- |D) http://www.dtone.orgWhat is the default attribute for class members (private/protected/public)?Public. I always thought that C++'s way just made for annoying extra typing when banging out quick code. A production quality class should always say it explicitly.
Nov 12 2001
"Axel Kittenberger" <axel dtone.org> wrote in news:9so2i6$nhi$1 digitaldaemon.com...Walter wrote:I think the compiler shouldn't compile a class with no 'public', 'private' or 'protected' at all. The user clearly forgotten to specify. Ciao"Pavel "EvilOne" Minayev" <evilone omen.ru> wrote in message news:9sdigb$2715$1 digitaldaemon.com...I say private would be better for quality code. Argueing for this is quite simple, if there is nothing standing there you can suppose that programmer simply forgot about the access attribute. [snip]What is the default attribute for class members (private/protected/public)?Public. I always thought that C++'s way just made for annoying extra typing when banging out quick code. A production quality class should always say it explicitly.
Nov 12 2001
"Axel Kittenberger" <axel dtone.org> wrote in message news:9so2i6$nhi$1 digitaldaemon.com...Walter wrote:I say private would be better for quality code. Argueing for this is quite simple, if there is nothing standing there you can suppose that programmer simply forgot about the access attribute. If he actually ment private, but public is default, he gets no compiler errors/warnings. If he actually ment public, but private is default, the compiler willpointhim on the failure.The thing is, when you omit the attribute at all, you get all members private, and the result is that class is completely useless. As for "actually ment private" - I believe that when declaring classes, it's better to define public members first, since there are more people who want to know the interface of the cass than those that are interested in implementation.
Nov 12 2001
What is the default calling convention for D functions - cdecl, stdcall, pascal, fastcall? BTW I wonder why you define stdcall convention as extern(Windows)? It's not WinAPI-only, there are stdcall specifiers in C, C++ and Pascal, and I believe that most programmers know it as stdcall. And in general, although convention is not a keyword, as stated in the specs, it looks like that, so - IMHO - it should be in lower-case. The same for extern(Pascal) - extern(pascal) seems to look better and more familiar especially to those who, like me, are used to Borland's compilers.
Nov 08 2001
Don't you find it the least bit presumptuous to make a calling convention used only by Windows that is called "stdcall"? If there were such a thing as an industry standard, I guess that's it, a de facto one, I guess naming it stdcall probably helped. ;) I'm not sure a language spec should define platform-specific runtime behavior; the programs should (in theory) be agnostic to the choice of platform. If you're curious as to Walter's first D compiler's default for the initial platform, Windows... well that seems to be a valid question. Sean "Pavel "EvilOne" Minayev" <evilone omen.ru> wrote in message news:9sdiqf$2721$1 digitaldaemon.com...What is the default calling convention for D functions - cdecl, stdcall, pascal, fastcall? BTW I wonder why you define stdcall convention as extern(Windows)? It's not WinAPI-only, there are stdcall specifiers in C, C++ and Pascal, and I believe that most programmers know it as stdcall. And in general, although convention is not a keyword, as stated in the specs, it looks like that, so - IMHO - it should be in lower-case. The same for extern(Pascal) - extern(pascal) seems to look better and more familiar especially to those who, like me, are used to Borland's compilers.
Nov 08 2001
"Sean L. Palmer" <spalmer iname.com> wrote in message news:9sdpc1$2b9f$1 digitaldaemon.com...Don't you find it the least bit presumptuous to make a calling convention used only by Windows that is called "stdcall"? If there were such a thing as an industry standard, I guess that's it, a de facto one, I guess naming it stdcall probably helped. ;)Yes, I know that it isn't actually "std". But it is well known as such, why rename?I'm not sure a language spec should define platform-specific runtime behavior; the programs should (in theory) be agnostic to the choice of platform. If you're curious as to Walter's first D compiler's default for the initial platform, Windows... well that seems to be a valid question.If compiler is to be of any use on Windows, it has to support at least stdcall in any way. BTW specs don't define any calling conventions other than C and D, so support for stdcall and pascal is purely implementation- dependent.
Nov 08 2001
None of them. I intend to have it (the default D calling convention) unspecified, so the compiler will be free to use whatever works best for the code gen for that particular function. This makes interprocedural optimizations possible. I strongly dislike the pointless proliferation of calling conventions found in win32. Since D must interface with existing C code, it must support them. Hence, the extern(spec) construct. Microsoft doesn't exactly use the stdcall for Windows API calls - first of all, it varies (pascal on 16 bit machines, syscall on OS/2), and second, they mangle the names differently than stdcall for system calls. After all, they are windows API calling conventions, and who (besides the compiler implementor) really cares what it is, so why not call it the "windows" calling convention? It's easy to remember <g>. I called it "Pascal" rather than "pascal" because it is conventionally capitalized, just like fortran is normally "FORTRAN". I suppose it doesn't matter one way or the other. "Pavel "EvilOne" Minayev" <evilone omen.ru> wrote in message news:9sdiqf$2721$1 digitaldaemon.com...What is the default calling convention for D functions - cdecl, stdcall, pascal, fastcall? BTW I wonder why you define stdcall convention as extern(Windows)? It's not WinAPI-only, there are stdcall specifiers in C, C++ and Pascal, and I believe that most programmers know it as stdcall. And in general, although convention is not a keyword, as stated in the specs, it looks like that, so - IMHO - it should be in lower-case. The same for extern(Pascal) - extern(pascal) seems to look better and more familiar especially to those who, like me, are used to Borland's compilers.
Nov 09 2001
"Walter" <walter digitalmars.com> wrote in message news:9sgcul$10f4$1 digitaldaemon.com...None of them. I intend to have it (the default D calling convention) unspecified, so the compiler will be free to use whatever works best forthecode gen for that particular function. This makes interprocedural optimizations possible. I strongly dislike the pointless proliferation of calling conventions found in win32.Optimizations are good, but what about assembler routines? I believe that order of arguments on stack is not really important since you can use their names instead, but who should clean the stack - callee or caller? BTW, another syntactic sugar suggestion - a short way to declare assembler rountines: make it so that body of function can consist of a single asm block: void DrawLine(int x1, int y1, int x2, int y2, int color) asm { // assembler code goes here } Or an "asm" attibute: void asm DrawLine(int x1, int y1, int x2, int y2, int color) { ... } This way, the only thing generated by the compiler itsel would be the typical entry code, everything else is on programmer's part. Could be handy.Microsoft doesn't exactly use the stdcall for Windows API calls - first of all, it varies (pascal on 16 bit machines, syscall on OS/2), and second, they mangle the names differently than stdcall for system calls. Afterall,they are windows API calling conventions, and who (besides the compiler implementor) really cares what it is, so why not call it the "windows" calling convention? It's easy to remember <g>.Okay, I give up. You can be very persuasive, you know. =) Concerning name mangling. Are you going to define a single scheme that must be used by each and any compiler, or is it implementation- defined?
Nov 09 2001
"Pavel "EvilOne" Minayev" <evilone omen.ru> wrote in message news:9sglrt$1ae5$1 digitaldaemon.com...Optimizations are good, but what about assembler routines? I believe that order of arguments on stack is not really important since you can use their names instead, but who should clean the stack - callee or caller?If you are writing assembler routines, the options are: 1) use the inline assembler, where you don't care about call/return conventions 2) declare the external assembler function with C call/return conventionsConcerning name mangling. Are you going to define a single scheme that must be used by each and any compiler, or is it implementation- defined?I'll define a scheme and recommend that people use it, though it won't be part of the language spec.
Nov 09 2001
"Walter" <walter digitalmars.com> wrote in message news:9si4hr$2ved$1 digitaldaemon.com...If you are writing assembler routines, the options are: 1) use the inline assembler, where you don't care about call/return conventions 2) declare the external assembler function with C call/return conventionsBTW what's the point in caller cleaning the stack? I always thought that callee, using RET n on x86, for example, can do it faster. Since you aren't going to support C-style varargs...
Nov 09 2001
"Pavel "EvilOne" Minayev" <evilone omen.ru> wrote in message news:9sik7a$7ed$1 digitaldaemon.com..."Walter" <walter digitalmars.com> wrote in message news:9si4hr$2ved$1 digitaldaemon.com...conventionsIf you are writing assembler routines, the options are: 1) use the inline assembler, where you don't care about call/return conventions 2) declare the external assembler function with C call/returnBTW what's the point in caller cleaning the stack? I always thought that callee, using RET n on x86, for example, can do it faster. Since you aren't going to support C-style varargs...The code generator can be clever and avoid any stack cleanups at all, which of course is faster.
Nov 10 2001
Walter wrote:None of them. I intend to have it (the default D calling convention) unspecified, so the compiler will be free to use whatever works best for the code gen for that particular function. This makes interprocedural optimizations possible. I strongly dislike the pointless proliferation of calling conventions found in win32.So any external code that calls into D code can only safely do so to a D function that is defined with a non-default calling convention? I guess that lets you control the entry points... -RB
Nov 09 2001
"Russell Borogove" <kaleja estarcion.com> wrote in message news:3BEC2016.D83E8ED3 estarcion.com...Walter wrote:theNone of them. I intend to have it (the default D calling convention) unspecified, so the compiler will be free to use whatever works best forofcode gen for that particular function. This makes interprocedural optimizations possible. I strongly dislike the pointless proliferationYes. <g> I want to leave the door open for aggressive interprocedural optimizations.calling conventions found in win32.So any external code that calls into D code can only safely do so to a D function that is defined with a non-default calling convention? I guess that lets you control the entry points...
Nov 09 2001
In article <9sb0c1$ceq$1 digitaldaemon.com>, "Pavel \EvilOne\ Minayev" <evilone omen.ru> wrote:Static attribute. Are static local variables supported?If you have public and private (etc.) attributes, you no longer appear to need static to make items private to a module. Of course, you still need them in functions and classes, but is there any other requirement for them at the top-level? (Especially for functions.)
Nov 08 2001
"Ben Cohen" <bc skygate.co.uk> wrote in message news:9sdsmg$2dca$1 digitaldaemon.com...^^^^^ LOL =)Static attribute. Are static local variables supported?If you have public and private (etc.) attributes, you no longer appear to need static to make items private to a module. Of course, you still need them in functions and classes, but is there any other requirement for them at the top-level? (Especially for functions.)
Nov 08 2001
I believe that extern() property states that function has no body, so the following is illegal: extern(Windows) int WindowProc() { } Is it so? If it is, how about WinAPI callbacks? Is it legal to define names for parameters of extern function? Is it legal to omit names of parameters of implemented function? Like that: extern(Windows) int LineTo(HDC hDc, int x, int y); void TimerProc(HWND, uint, uint id, uint) { switch (id) { ... } } How are function pointers declared? I remember a discussion of this topic not long ago, but what is the official way? Are pointers to methods supported? Are they like in Delphi (kewl) or in C++ (almost useless)?
Nov 09 2001
"Pavel "EvilOne" Minayev" <evilone omen.ru> wrote in message news:9sglru$1ae5$2 digitaldaemon.com...I believe that extern() property states that function has no body, so the following is illegal: extern(Windows) int WindowProc() { } Is it so? If it is, how about WinAPI callbacks?It is legal, despite what the doc says (!).Is it legal to define names for parameters of extern function? Is it legal to omit names of parameters of implemented function? Like that: extern(Windows) int LineTo(HDC hDc, int x, int y); void TimerProc(HWND, uint, uint id, uint) { switch (id) { ... } }Yes.How are function pointers declared? I remember a discussion of this topic not long ago, but what is the official way?I haven't done that yet.Are pointers to methods supported?No. Pointers to methods are nothing but confusion.Are they like in Delphi (kewl) or in C++ (almost useless)?How do they work in Delphi?
Nov 09 2001
"Walter" <walter digitalmars.com> wrote in message news:9si93q$o4$2 digitaldaemon.com...My suggestion would be something like: int(int x, int y) OnMouseMove;How are function pointers declared? I remember a discussion of this topic not long ago, but what is the official way?I haven't done that yet.Disagreed. They are really useful for writing callback- based event-driven system - GUI toolkits are a typical example of this. Compare VCL, which relies on pointers to methods, and MFC, which uses map tables. Which one is easier?Are pointers to methods supported?No. Pointers to methods are nothing but confusion.type TButton = class OnMouseMove: procedure(x, y: integer) of object; end; TMyForm = class(TForm) cmdOk: TButton; ... constructor Create; procedure cmdOk_MouseMove(x, y: integer); end; constructor TMyForm.Create; begin cmdOk.OnMouseMove := cmdOk_MouseMove; end; procedure TMyForm.cmdOk_MouseMove(x, y: integer) begin ... end; In other words, in Delphi pointer to method is universal - it can point to any method of any class, whose parameters and return type matches the declaration. Also, unlike C++ one, it does store the pointer to object to which method belongs! But these are technical details, what it gives to programmers is ability to define callbacks for methods in absolutely the same way as for global functions, and compiler takes care of the rest. Nothing close compared to weird and useless C++ method pointers. The entire VCL library is built on this system - and I believe it's one of the easiest, yet powerful, GUI toolkits for Windows.Are they like in Delphi (kewl) or in C++ (almost useless)?How do they work in Delphi?
Nov 09 2001
BTW in C++Builder, pointers to methods are declared using __closure keyword. Isn't that funny =)
Nov 10 2001
On second thought, I came to an idea that it'd be nice if all function pointers would be "universal" - that is, able to point to global function as well to method. Internally, it would be represented by a simple struct: struct { Object object; void* function; } If pointer is to global function, the .object field is null, otherwise, its value is used as "this" pointer when calling method. This requires twice as large memory for function pointers... But memory isn't an issue nowadays, especially considering that there aren't many function pointers in programs, and it is very unlikely to have arrays of them. On other hand, methods could be used in any situation where callback is required, which can be damn useful. As an example, consider WindowProc callback. In MDI application, there are several (child) windows which are represented by instances of a single class. It would be great if I could use a method as a WindowProc, but no, I have to define a single static method, make a linked-list of all windows and scan through it each time I get a message to determine which window should handle it... of course, nothing can be done here, but at least similar situations in libraries written in D could be prevented.
Nov 10 2001
"Pavel "EvilOne" Minayev" <evilone omen.ru> wrote in message news:9srips$pi$1 digitaldaemon.com...Sooo?I am with this on Pavel. They are *very* usefull, I know so from experience. MFC message maps suck :( -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail
Feb 05 2002
If module B imports module C, and module A imports B, does A import C?
Nov 10 2001
"Pavel "EvilOne" Minayev" <evilone omen.ru> wrote in message news:9sjljv$v8m$1 digitaldaemon.com...If module B imports module C, and module A imports B, does A import C?Scoping issues aside, yes.
Nov 10 2001
"Walter" <walter digitalmars.com> wrote in message news:9skeha$1dh9$2 digitaldaemon.com..."Pavel "EvilOne" Minayev" <evilone omen.ru> wrote in message news:9sjljv$v8m$1 digitaldaemon.com...So there's no way to import a module for my own, "private" use? Something like that: import vector; // this is visible to everybody private import math; // this is used internally and thus is visible only to myself And then, forbid any constants and types from private- imported modules to be used in public declarations?If module B imports module C, and module A imports B, does A import C?Scoping issues aside, yes.
Nov 11 2001
Hmm, private imports. That might be a good idea! "Pavel "EvilOne" Minayev" <evilone omen.ru> wrote in message news:9slg8k$23nj$1 digitaldaemon.com..."Walter" <walter digitalmars.com> wrote in message news:9skeha$1dh9$2 digitaldaemon.com..."Pavel "EvilOne" Minayev" <evilone omen.ru> wrote in message news:9sjljv$v8m$1 digitaldaemon.com...So there's no way to import a module for my own, "private" use? Something like that: import vector; // this is visible to everybody private import math; // this is used internally and thus is visible only to myself And then, forbid any constants and types from private- imported modules to be used in public declarations?If module B imports module C, and module A imports B, does A import C?Scoping issues aside, yes.
Nov 19 2001
On Mon, 19 Nov 2001 09:44:01 +0000, Walter wrote:Hmm, private imports. That might be a good idea!Actually, could you explain why public imports are a good idea (in particular as a default)?
Nov 20 2001
"Ben Cohen" <bc skygate.co.uk> wrote in message news:9td75g$4ep$1 digitaldaemon.com...On Mon, 19 Nov 2001 09:44:01 +0000, Walter wrote:I agree. Module imports must be private by default. This would provide better control over them.Hmm, private imports. That might be a good idea!Actually, could you explain why public imports are a good idea (in particular as a default)?
Nov 20 2001
"Ben Cohen" <bc skygate.co.uk> wrote in message news:9td75g$4ep$1 digitaldaemon.com...On Mon, 19 Nov 2001 09:44:01 +0000, Walter wrote:We obviously are approaching this from different directions :-)Hmm, private imports. That might be a good idea!Actually, could you explain why public imports are a good idea (in particular as a default)?
Nov 20 2001
On Tue, 20 Nov 2001 17:38:05 +0000, Walter wrote:Yes, I think so too. OK then, first I'll explain why I think private imports would be a better default :-) Suppose you have a module A which imports other modules B, C, and D. I think that it is more likely that you don't want all the names in B, C and D to be imported into an application when you import A. (E.g., A = http library, B = networking, etc.) Not importing B, C and D when the calling application imports A would be better software engineering; otherwise you would have names added to your namespace which you didn't expect. Public imports are a bit like inheritance (and you don't make "public" the default attribute for class members). Of course, perhaps you are writing an application which needs to use module B independently (e.g., it uses http, and also an extra networking protocol); you can then "import A, B;" in your application. In the presumably less common case where importing A always requires the application to import B explicitly, then you do need a public import. (E.g., the application has to open the connection itself for the http library to work?) But I think the private import is the more common and natural default.We obviously are approaching this from different directions :-)Hmm, private imports. That might be a good idea!Actually, could you explain why public imports are a good idea (in particular as a default)?
Nov 21 2001
Overall, I like this idea a lot. However, I would note that, unlike inheritance, if you privately import a library and then another module imports the same library, we don't want duplicate symbols of everything. It seems to me that we should have only one copy of the module, no matter how many of the chains of modules import it. Thus, it really isn't a "private" import...it's more of an "extern/intern" issue. I would suggest that the "public" import syntax then be: extern import A,B; while the "private" syntax is just: import C,D; Also, a side effect of less namespace pollution is that you don't have as many dependencies at build time. Say module A imports B&C privately, and D imports A. If you modify B, then A will need to be rebuilt...but D does not. If all imports are public, then a modification to B causes a rebuild of D. On the other hand, if A also includes a (public) import of E, then modifying E causes rebuilds of both A and D, since both contain the names & types in it. -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Nov 21 2001
"Ben Cohen" <bc skygate.co.uk> wrote in message news:9tfs9k$1uhi$1 digitaldaemon.com...Public imports are a bit like inheritance (and you don't make "public" the default attribute for class members).Actually, D does <g>. The idea is to minimize the fluff for quick & dirty programs, while providing the facilities for the more carefully engineered production code.
Nov 22 2001
On Fri, 23 Nov 2001 00:28:09 +0000, Walter wrote:"Ben Cohen" <bc skygate.co.uk> wrote in message news:9tfs9k$1uhi$1 digitaldaemon.com...Oh, I missed that -- so the keyword "public" would be redundant for class members? That means either that protected (say) should be the default for classes, or else my argument doesn't work any more, depending on which way you look at it. ;)Public imports are a bit like inheritance (and you don't make "public" the default attribute for class members).Actually, D does <g>. The idea is to minimize the fluff for quick & dirty programs, while providing the facilities for the more carefully engineered production code.
Nov 23 2001
"Ben Cohen" <bc skygate.co.uk> wrote in message news:9tl3ju$1jdj$1 digitaldaemon.com...On Fri, 23 Nov 2001 00:28:09 +0000, Walter wrote:It is the default, but is not redundant. For example, if you switch to private, with public you can switch back again."Ben Cohen" <bc skygate.co.uk> wrote in message news:9tfs9k$1uhi$1 digitaldaemon.com...Oh, I missed that -- so the keyword "public" would be redundant for class members?Public imports are a bit like inheritance (and you don't make "public" the default attribute for class members).Actually, D does <g>. The idea is to minimize the fluff for quick & dirty programs, while providing the facilities for the more carefully engineered production code.That means either that protected (say) should be the default for classes, or else my argument doesn't work any more, depending on which way you look at it. ;)<g>
Nov 23 2001