D - some questions concerning D specs
- "Pavel \"EvilOne\" Minayev" <evilone omen.ru> Nov 07 2001
- "Walter" <walter digitalmars.com> Nov 08 2001
- "Pavel \"EvilOne\" Minayev" <evilone omen.ru> Nov 08 2001
- Russ Lewis <spamhole-2001-07-16 deming-os.org> Nov 08 2001
- "Walter" <walter digitalmars.com> Nov 09 2001
- "Sean L. Palmer" <spalmer iname.com> Nov 09 2001
- "Walter" <walter digitalmars.com> Nov 09 2001
- "Pavel \"EvilOne\" Minayev" <evilone omen.ru> Nov 08 2001
- Russ Lewis <spamhole-2001-07-16 deming-os.org> Nov 08 2001
- "Pavel \"EvilOne\" Minayev" <evilone omen.ru> Nov 09 2001
- Russ Lewis <spamhole-2001-07-16 deming-os.org> Nov 09 2001
- "Pavel \"EvilOne\" Minayev" <evilone omen.ru> Nov 09 2001
- "Walter" <walter digitalmars.com> Nov 09 2001
- "Walter" <walter digitalmars.com> Nov 09 2001
- "Pavel \"EvilOne\" Minayev" <evilone omen.ru> Nov 09 2001
- "Walter" <walter digitalmars.com> Nov 09 2001
- "Pavel \"EvilOne\" Minayev" <evilone omen.ru> Nov 09 2001
- "Walter" <walter digitalmars.com> Nov 10 2001
- a <a b.c> Nov 10 2001
- "Pavel \"EvilOne\" Minayev" <evilone omen.ru> Nov 11 2001
- "Roberto Mariottini" <rmariottini lycosmail.com> Nov 12 2001
- "Pavel \"EvilOne\" Minayev" <evilone omen.ru> Nov 12 2001
- Roland <rv ronetech.com> Nov 12 2001
- "Walter" <walter digitalmars.com> Nov 29 2001
- "Robert W. Cunningham" <rwc_2001 yahoo.com> Nov 29 2001
- Ben Cohen <bc skygate.co.uk> Nov 30 2001
- Roland <rv ronetech.com> Nov 30 2001
- Russ Lewis <spamhole-2001-07-16 deming-os.org> Nov 30 2001
- nancyetroland <nancyetroland free.fr> Nov 29 2001
- Russ Lewis <spamhole-2001-07-16 deming-os.org> Nov 30 2001
- nancyetroland <nancyetroland free.fr> Dec 01 2001
- Russ Lewis <spamhole-2001-07-16 deming-os.org> Dec 01 2001
- "Walter" <walter digitalmars.com> Dec 01 2001
- "Pavel Minayev" <evilone omen.ru> Dec 02 2001
- "Pavel Minayev" <evilone omen.ru> Dec 02 2001
- "Walter" <walter digitalmars.com> Dec 02 2001
- "Pavel Minayev" <evilone omen.ru> Dec 02 2001
- "Walter" <walter digitalmars.com> Dec 03 2001
- "Sean L. Palmer" <spalmer iname.com> Dec 03 2001
- "Pavel Minayev" <evilone omen.ru> Dec 03 2001
- "Walter" <walter digitalmars.com> Dec 03 2001
- "Pavel Minayev" <evilone omen.ru> Dec 03 2001
- "Walter" <walter digitalmars.com> Dec 04 2001
- "Pavel Minayev" <evilone omen.ru> Dec 04 2001
- Roland <rv ronetech.com> Dec 11 2001
- "Pavel Minayev" <evilone omen.ru> Dec 12 2001
- NancyEtRoland <nancyetroland free.fr> Dec 22 2001
- "Pavel Minayev" <evilone omen.ru> Dec 23 2001
- NancyEtRoland <nancyetroland free.fr> Dec 26 2001
- Russ Lewis <spamhole-2001-07-16 deming-os.org> Dec 25 2001
- NancyEtRoland <nancyetroland free.fr> Dec 26 2001
- Russ Lewis <spamhole-2001-07-16 deming-os.org> Dec 26 2001
- "Pavel Minayev" <evilone omen.ru> Dec 26 2001
- Russ Lewis <spamhole-2001-07-16 deming-os.org> Dec 26 2001
- "Sean L. Palmer" <spalmer iname.com> Dec 02 2001
- "Pavel Minayev" <evilone omen.ru> Dec 02 2001
- a <a b.c> Dec 02 2001
- Charles Hixson <charleshixsn earthlink.net> Dec 03 2001
- "Pavel Minayev" <evilone omen.ru> Dec 03 2001
- Russ Lewis <spamhole-2001-07-16 deming-os.org> Dec 03 2001
- Roland <rv ronetech.com> Dec 04 2001
- "Walter" <walter digitalmars.com> Nov 30 2001
- Russ Lewis <spamhole-2001-07-16 deming-os.org> Nov 09 2001
- Russell Borogove <kaleja estarcion.com> Nov 09 2001
- "Sean L. Palmer" <spalmer iname.com> Nov 09 2001
- "Walter" <walter digitalmars.com> Nov 09 2001
- la7y6nvo shamko.com Nov 10 2001
- Axel Kittenberger <axel dtone.org> Nov 12 2001
- "Roberto Mariottini" <rmariottini lycosmail.com> Nov 12 2001
- "Pavel \"EvilOne\" Minayev" <evilone omen.ru> Nov 12 2001
- "Pavel \"EvilOne\" Minayev" <evilone omen.ru> Nov 08 2001
- "Sean L. Palmer" <spalmer iname.com> Nov 08 2001
- "Pavel \"EvilOne\" Minayev" <evilone omen.ru> Nov 08 2001
- "Walter" <walter digitalmars.com> Nov 09 2001
- "Pavel \"EvilOne\" Minayev" <evilone omen.ru> Nov 09 2001
- "Walter" <walter digitalmars.com> Nov 09 2001
- "Pavel \"EvilOne\" Minayev" <evilone omen.ru> Nov 09 2001
- "Walter" <walter digitalmars.com> Nov 10 2001
- Russell Borogove <kaleja estarcion.com> Nov 09 2001
- "Walter" <walter digitalmars.com> Nov 09 2001
- "Ben Cohen" <bc skygate.co.uk> Nov 08 2001
- "Pavel \"EvilOne\" Minayev" <evilone omen.ru> Nov 08 2001
- "Pavel \"EvilOne\" Minayev" <evilone omen.ru> Nov 09 2001
- "Walter" <walter digitalmars.com> Nov 09 2001
- "Pavel \"EvilOne\" Minayev" <evilone omen.ru> Nov 09 2001
- "Pavel \"EvilOne\" Minayev" <evilone omen.ru> Nov 10 2001
- "Pavel \"EvilOne\" Minayev" <evilone omen.ru> Nov 10 2001
- "Pavel \"EvilOne\" Minayev" <evilone omen.ru> Nov 13 2001
- "OddesE" <OddesE_XYZ hotmail.com> Feb 05 2002
- "Pavel \"EvilOne\" Minayev" <evilone omen.ru> Nov 10 2001
- "Walter" <walter digitalmars.com> Nov 10 2001
- "Pavel \"EvilOne\" Minayev" <evilone omen.ru> Nov 11 2001
- "Walter" <walter digitalmars.com> Nov 19 2001
- Ben Cohen <bc skygate.co.uk> Nov 20 2001
- "Pavel Minayev" <evilone omen.ru> Nov 20 2001
- "Walter" <walter digitalmars.com> Nov 20 2001
- Ben Cohen <bc skygate.co.uk> Nov 21 2001
- Russ Lewis <spamhole-2001-07-16 deming-os.org> Nov 21 2001
- "Walter" <walter digitalmars.com> Nov 22 2001
- Ben Cohen <bc skygate.co.uk> Nov 23 2001
- "Walter" <walter digitalmars.com> Nov 23 2001
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...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
thrown.
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.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.
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)?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>.
object.class, probably?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.
This, however, involves things like virtual constructors.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, from withing B, I'd simply write: A.foo();Static methods. Can they be overridden? Can they be called in the same manner as non-static ones?
Yes, yes.
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?
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...Array slicing. What happens when I use the form a[x..y], and x is greater than y?
thrown.
the loop (or am I wrong?), it simply won't do anything.
In general, if an exception will be thrown if checking is turned on, undefined behavior will result if checking is turned off.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?
finalizer, and (in the future) access to any classes it depends on.
That's an open possibility.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.If I have a reference to object, how do I get the appropriate Class object?
<g>.
Or .classinfo. Something like that.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?
B b; b.A.foo();
A.foo();
Yes.Static methods. Can they be overridden? Can they be called in the same manner as non-static ones?
class A { static void B() { ... } } A a; A::B(); a.B(); // the same?
Yes.is legal? If it is, will B() be aware that it is called in a different way?
Yes, yes.
Nov 09 2001
So the following: class A { static void B() { ... } } A a; A::B(); a.B(); // the same?
Yes.
Are you saying that D supports use of the :: operator? Sean
Nov 09 2001
"Sean L. Palmer" <spalmer iname.com> wrote in message news:9sh8nm$237g$1 digitaldaemon.com...So the following: class A { static void B() { ... } } A a; A::B(); a.B(); // the same?
Yes.
Are you saying that D supports use of the :: operator? Sean
No, sorry, A::B() is not allowed. Use A.B()
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(); } } Question #1: how do I call the global X() from A.Y() (since simply typing X() would invoke A.X())? Question #2: how do I access method Y() of class B from A.Y() (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(); } } Question #1: how do I call the global X() from A.Y() (since simply typing X() would invoke A.X())?
Since you know the module name, why not: <module>.X();Question #2: how do I access method Y() of class B from A.Y() (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...Question #1: how do I call the global X() from A.Y() (since simply typing X() would invoke A.X())?
Since you know the module name, why not: <module>.X();
And what if there's a local variable or class property with the same name as module?Question #2: how do I access method Y() of class B from A.Y() (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; }; }
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.
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...Question #1: how do I call the global X() from A.Y() (since simply typing X() would invoke A.X())?
Since you know the module name, why not: <module>.X();
And what if there's a local variable or class property with the same name as module?
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))) ]
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 suppose
Definitely. 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...Question #1: how do I call the global X() from A.Y() (since simply typing X() would invoke A.X())?
Since you know the module name, why not: <module>.X();
And what if there's a local variable or class property with the same name as module?Question #2: how do I access method Y() of class B from A.Y() (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; }; }
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.
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();
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(); } } Question #1: how do I call the global X() from A.Y() (since simply typing X() would invoke A.X())?
Prefix it with the module name. Assume the module name is foo: foo.X()Question #2: how do I access method Y() of class B from A.Y() (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...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.
Yes, yes! Should we start collecting votes for a petition? =)Question #2: how do I access method Y() of class B from A.Y() (since B.Y() will invoke method Y() of object C)?
A.B.Y()
I mentioned it already, but... What if class A contains variable B? Will the above code do what we expect it to?
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...Suppose I have the following declaration: int* x, y; Is y an int or a pointer to int?
otherwise.
Should we start collecting votes for a petition? =)
I'm more interested in compelling arguments (!)Question #2: how do I access method Y() of class B from A.Y() (since B.Y() will invoke method Y() of object C)?
What if class A contains variable B? Will the above code do what we expect it to?
A.super.Y()
Nov 09 2001
"Walter" <walter digitalmars.com> wrote in message news:9si4hs$2ved$3 digitaldaemon.com...What if class A contains variable B? Will the above code do what we expect it to?
A.super.Y()
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? =)
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...What if class A contains variable B? Will the above code do what we expect it to?
A.super.Y()
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? =)
A.super.dee.duper.B() <g>
Nov 10 2001
Walter wrote:"Pavel "EvilOne" Minayev" <evilone omen.ru> wrote in message"Walter" <walter digitalmars.com> wrote in messageSuppose I have the following declaration: int* x, y; Is y an int or a pointer to int?
otherwise.
Should we start collecting votes for a petition? =)
I'm more interested in compelling arguments (!)
How 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
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...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...
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. Ciao
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 best
remove 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'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...
I think you're right.
Nov 29 2001
Walter wrote:"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'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...
I think you're right.
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
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
int*[]* x, y, *z; This should be an error! The "correct" form should require z to be on a separate line.
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 Roland
Nov 30 2001
Roland wrote:int* p1,p2,p3; <- correct, all are pointers int *p1,p2,p3; <- NOT correct
Are 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:int* p1,p2,p3; <- correct, all are pointers int *p1,p2,p3; <- NOT correct
Are you stating that it currently is a syntax error, or that you think it should be?
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. Roland
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 more
people (are you lurking, Walter?) about whether it is technically feasible
cases 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 to
C: int (*fp)(args); // ugly, but servicable D: int (*)(args) fp; // ?? int (args)* fp; // ?? arrgh
Solution: 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...And for pointers to methods, I'd suggest the following: int.(args) mp;
I'm trying to avoid pointers to members <g>.
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... } }
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.
just brings us back around to how to ease the passing of control back into
real actual object, the transmission of the this pointer has to be done somehow, and that just makes the programmer write forwarding functions
an 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 able
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
think.
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 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
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?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.
Dec 03 2001
"Pavel Minayev" <evilone omen.ru> wrote in message news:9uhsjq$1lb3$1 digitaldaemon.com...significant complexity involved with getting them implemented right.
You have to generate things like thunks. Ugh.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
#$(*% pain, and won't work in D since we don't have templates there.
--
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 a #$(*% pain, and won't work in D since we don't have templates there.
I 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 and
ArgType. The point here is that, using templates, I can create an
structure (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; // ?? arrgh
A 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:C: int (*fp)(args); // ugly, but servicable D: int (*)(args) fp; // ?? int (args)* fp; // ?? arrgh
A 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 :(
int function(args)* fp1,fp2; // requires new keyword 'function' //pointed type is defined before '*' Roland
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
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.
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))) ]
Nov 09 2001
Walter wrote:"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.
I'd personally lobby for the default attribute be "compilererror". That's just me though. _R
Nov 09 2001
"Walter" <walter digitalmars.com> wrote in message news:9sh1ca$1pn2$2 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
when banging out quick code. A production quality class should always say
explicitly.
Agreed. I suppose inheritance is also by default public?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.
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.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...What is the default attribute for class members (private/protected/public)?
when banging out quick code. A production quality class should always
itexplicitly.
Yes.Suppose I have the following declaration: int* x, y; Is y an int or a pointer to int?
otherwise.
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
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 message
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 wrote:"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.
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.org
Nov 12 2001
"Axel Kittenberger" <axel dtone.org> wrote in news:9so2i6$nhi$1 digitaldaemon.com...Walter wrote:"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.
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]
I think the compiler shouldn't compile a class with no 'public', 'private' or 'protected' at all. The user clearly forgotten to specify. Ciao
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 will
him 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 for
code 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. After
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 conventions
BTW 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...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
BTW 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: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
code gen for that particular function. This makes interprocedural optimizations possible. I strongly dislike the pointless proliferation
calling conventions found in win32.
so to a D function that is defined with a non-default calling convention? I guess that lets you control the entry points...
Yes. <g> I want to leave the door open for aggressive interprocedural optimizations.
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...Static attribute. Are static local variables supported?
LOL =)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...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.
My suggestion would be something like: int(int x, int y) OnMouseMove;Are pointers to methods supported?
No. Pointers to methods are nothing but confusion.
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 they like in Delphi (kewl) or in C++ (almost useless)?
How do they work in Delphi?
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.
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...If module B imports module C, and module A imports B, does A import C?
Scoping issues aside, yes.
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?
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...If module B imports module C, and module A imports B, does A import C?
Scoping issues aside, yes.
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?
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: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)?
I agree. Module imports must be private by default. This would provide better control over them.
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:Hmm, private imports. That might be a good idea!
particular as a default)?
We obviously are approaching this from different directions :-)
Nov 20 2001
On Tue, 20 Nov 2001 17:38:05 +0000, Walter wrote:Hmm, private imports. That might be a good idea!
particular as a default)?
We obviously are approaching this from different directions :-)
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.
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...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.
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. ;)
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:"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.
members?
It is the default, but is not redundant. For example, if you switch to private, with public you can switch back again.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









Russ Lewis <spamhole-2001-07-16 deming-os.org> 