digitalmars.D.learn - Code fails with linker error. Why?
- eles (49/49) Oct 03 2014 This is under Linux 64 with both dmd 2.066 (and latest gdc-4.9):
- John Colvin (6/9) Oct 03 2014 that means you have a definition of formula elsewhere (which the
- eles (21/30) Oct 03 2014 Thanks, but still. The compiler shall not let that code pass down
- Chris Nicholson-Sauls (6/6) Oct 04 2014 In the original you are casting an int to a pointer type, which
- eles (3/9) Oct 04 2014 Yes, you are right. Then it's cast back when assigning.
- eles (5/11) Oct 04 2014 But this also means that the cast is useless there, so there is
- John Colvin (24/42) Oct 04 2014 Sorry, but that's just not how it works. There is no requirement
- eles (2/9) Oct 04 2014 No "extern" required?...
- ketmar via Digitalmars-d-learn (3/4) Oct 04 2014 nope.
- John Colvin (13/24) Oct 04 2014 nope, no extern required. The extern you are referring to is the
- ketmar via Digitalmars-d-learn (6/9) Oct 04 2014 On Sat, 04 Oct 2014 10:27:16 +0000
- eles (3/8) Oct 04 2014 Yes, that too. Is even worse.
- John Colvin (22/33) Oct 04 2014 Yes, you can. You just have to get the mangling right.
- John Colvin (22/57) Oct 04 2014 Inheritance works too:
- ketmar via Digitalmars-d-learn (16/33) Oct 04 2014 On Sat, 04 Oct 2014 11:01:28 +0000
- John Colvin (38/75) Oct 04 2014 good catch. This works for me, but it's probably not portable due
- ketmar via Digitalmars-d-learn (11/19) Oct 04 2014 On Sat, 04 Oct 2014 15:29:55 +0000
- John Colvin (5/21) Oct 04 2014 It is a little noisy, but really very little. The only extra
- ketmar via Digitalmars-d-learn (11/14) Oct 04 2014 On Sat, 04 Oct 2014 16:52:08 +0000
- eles (13/32) Oct 06 2014 That's hackish, bad and convoluted. And it does not/should not
- John Colvin (8/45) Oct 06 2014 s/especially/only
- eles (8/24) Oct 06 2014 Well, in the OP example, imagine that I was trying to compile
- John Colvin (6/31) Oct 06 2014 This isn't a problem. You're not going to get the name-mangling
- eles (8/22) Oct 06 2014 It is. I could erase the definition of an identical class in
- John Colvin (17/36) Oct 06 2014 Unless I misunderstand you, this can't happen. Class methods are
- ketmar via Digitalmars-d-learn (20/25) Oct 06 2014 On Mon, 06 Oct 2014 11:54:55 +0000
- John Colvin (7/34) Oct 06 2014 D is very amenable to slightly hackish code.
- ketmar via Digitalmars-d-learn (25/35) Oct 06 2014 On Mon, 06 Oct 2014 15:44:34 +0000
- eles (2/18) Oct 06 2014 So, you admit it is a hack! Gotcha!
- John Colvin (4/26) Oct 06 2014 In order to get access to private variables from another
- eles (2/12) Oct 06 2014 I know. Was not serious.
- eles (3/43) Oct 04 2014 This seem to allow an entire class of problems, by linking
This is under Linux 64 with both dmd 2.066 (and latest gdc-4.9): ================================================================= class ShapeSurface(T) { public: int formula(); int getSurfaceBy100() { int surface; surface = cast(T *)this.formula(); return surface*100; }; }; class Square: ShapeSurface!Square { public: int squareSize = 8; override int formula() { return squareSize*squareSize; } }; int main() { Square square = new Square(); square.getSurfaceBy100(); return 0; } ================================================================= It fails with linker error: dmd app.d app.o:(.data._D3app31__T12ShapeSurfaceTC3app6SquareZ12ShapeSu face6__vtblZ+0x28): undefined reference to `_D3app31__T12ShapeSurfaceTC3app6SquareZ12ShapeSurface7formulaMFZi' collect2: error: ld returned 1 exit status --- errorlevel 1 OK, maybe the cast is broken (well, to a pointer...), so changed this: surface = cast(T *)this.formula(); into this: T cls = cast(T)this; surface = cls.formula(); giving: dmd app.d app.o:(.data._D3app31__T12ShapeSurfaceTC3app6SquareZ12ShapeSu face6__vtblZ+0x28): undefined reference to `_D3app31__T12ShapeSurfaceTC3app6SquareZ12ShapeSurface7formulaMFZi' collect2: error: ld returned 1 exit status --- errorlevel 1 So, if you could tell me: 1) Why the compiler defer to the linker 2) What is the CRTP equivalent here Many thanks.
Oct 03 2014
On Friday, 3 October 2014 at 15:44:16 UTC, eles wrote:class ShapeSurface(T) { public: int formula();that means you have a definition of formula elsewhere (which the linker tries to find, but obviously fails. What you want is class ShapeSurface(T) { public: abstract int formula();
Oct 03 2014
On Friday, 3 October 2014 at 15:47:33 UTC, John Colvin wrote:On Friday, 3 October 2014 at 15:44:16 UTC, eles wrote:Thanks, but still. The compiler shall not let that code pass down to the linker. It has everything it needs to not do that, or it shall have. Linker errors shall be simply because the libraries are not in place (either not installed, either linking path not correctly configured, either broken versions of those libraries). Then, a quirk of D: this passes and works correctly: surface = cast(T *)this.formula(); this segfaults the produced binary: surface = (cast(T *)this).formula(); this fails: surface = cast(T)this.formula(); with app.d(8): Error: cannot cast this.formula() of type int to app.Square while one has to throw in parentheses to make it work (correctly) once again: surface = (cast(T)this).formula(); Isn't this funny, that you have to throw in parentheses depending on the type of the type you cast to?class ShapeSurface(T) { public: int formula();that means you have a definition of formula elsewhere (which the linker tries to find, but obviously fails. What you want is class ShapeSurface(T) { public: abstract int formula();
Oct 03 2014
In the original you are casting an int to a pointer type, which is legitimate (although rarely a good idea). The other side of the matter is simply precedence. cast(T)a.b; Is really the same as: cast(T)(a.b);
Oct 04 2014
On Saturday, 4 October 2014 at 09:39:12 UTC, Chris Nicholson-Sauls wrote:In the original you are casting an int to a pointer type, which is legitimate (although rarely a good idea). The other side of the matter is simply precedence. cast(T)a.b; Is really the same as: cast(T)(a.b);Yes, you are right. Then it's cast back when assigning.
Oct 04 2014
On Saturday, 4 October 2014 at 09:39:12 UTC, Chris Nicholson-Sauls wrote:In the original you are casting an int to a pointer type, which is legitimate (although rarely a good idea). The other side of the matter is simply precedence. cast(T)a.b; Is really the same as: cast(T)(a.b);But this also means that the cast is useless there, so there is no compile-time binding, so no CRTP. Anyway, it ws just a game to write the equivalent.
Oct 04 2014
On Saturday, 4 October 2014 at 04:02:46 UTC, eles wrote:On Friday, 3 October 2014 at 15:47:33 UTC, John Colvin wrote:Sorry, but that's just not how it works. There is no requirement for the definition of a function to be found in the same compilation unit as it's declaration. // a.d void foo(); void main() { foo(); } // b.d import std.stdio; void foo() { writeln("Hello World"); } $ ls a.d b.d $ dmd b.d -c $ ls a.d b.d b.o $ dmd a.d b.o $ ls a a.d a.o b.d b.o $ ./a Hello World So the compiler has no way of knowing whether you've forgotten to include a definition, or whether it's simply sitting in some other object file / library / whatever. The linker, however, can know, hence the linker error.On Friday, 3 October 2014 at 15:44:16 UTC, eles wrote:Thanks, but still. The compiler shall not let that code pass down to the linker. It has everything it needs to not do that, or it shall have. Linker errors shall be simply because the libraries are not in place (either not installed, either linking path not correctly configured, either broken versions of those libraries).class ShapeSurface(T) { public: int formula();that means you have a definition of formula elsewhere (which the linker tries to find, but obviously fails. What you want is class ShapeSurface(T) { public: abstract int formula();
Oct 04 2014
On Saturday, 4 October 2014 at 10:27:18 UTC, John Colvin wrote:On Saturday, 4 October 2014 at 04:02:46 UTC, eles wrote:On Friday, 3 October 2014 at 15:47:33 UTC, John Colvin wrote:On Friday, 3 October 2014 at 15:44:16 UTC, eles wrote:So the compiler has no way of knowing whether you've forgotten to include a definition, or whether it's simply sitting in some other object file / library / whatever. The linker, however, can know, hence the linker error.No "extern" required?...
Oct 04 2014
On Sat, 04 Oct 2014 10:37:39 +0000 eles via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:No "extern" required?...nope.
Oct 04 2014
On Saturday, 4 October 2014 at 10:37:40 UTC, eles wrote:On Saturday, 4 October 2014 at 10:27:18 UTC, John Colvin wrote:nope, no extern required. The extern you are referring to is the storage class http://dlang.org/declaration.html#extern and is for variables.On Saturday, 4 October 2014 at 04:02:46 UTC, eles wrote:On Friday, 3 October 2014 at 15:47:33 UTC, John Colvin wrote:On Friday, 3 October 2014 at 15:44:16 UTC, eles wrote:So the compiler has no way of knowing whether you've forgotten to include a definition, or whether it's simply sitting in some other object file / library / whatever. The linker, however, can know, hence the linker error.No "extern" required?...This seem to allow an entire class of problems, by linking against long-time forgotten functions...It's the core functionality that allows you to link to a function in a library without having the entire source available. You have a declaration, but the implementation is in another object file / library. D is slightly tighter than C wrt all this. In C, you can just call functions without even having a declaration, the compiler will assume the argument types from what you passed in. A forgotten #include and compiling without warnings = horrific bugs in C. In D the declaration is required.
Oct 04 2014
On Sat, 04 Oct 2014 10:27:16 +0000 John Colvin via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:Sorry, but that's just not how it works. There is no requirement=20 for the definition of a function to be found in the same=20 compilation unit as it's declaration.is there any possibility to declare *class* *method* in one file and to implement it in another? O_O i doubt so.
Oct 04 2014
On Saturday, 4 October 2014 at 10:38:32 UTC, ketmar via Digitalmars-d-learn wrote:On Sat, 04 Oct 2014 10:27:16 +0000 John Colvin via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:is there any possibility to declare *class* *method* in oneYes, that too. Is even worse.
Oct 04 2014
On Saturday, 4 October 2014 at 10:38:32 UTC, ketmar via Digitalmars-d-learn wrote:On Sat, 04 Oct 2014 10:27:16 +0000 John Colvin via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:Yes, you can. You just have to get the mangling right. // methodLink.d class A { void foo(); } void main() { auto a = new A; a.foo(); } // missingMethod.d import methodLink; import std.stdio; pragma(mangle, A.foo.mangleof) void foo() { writeln("Hello World"); } $ dmd missingMethod.d -c $ dmd methodLink.d missingMethod.o $ ./methodLink Hello WorldSorry, but that's just not how it works. There is no requirement for the definition of a function to be found in the same compilation unit as it's declaration.is there any possibility to declare *class* *method* in one file and to implement it in another? O_O i doubt so.
Oct 04 2014
On Saturday, 4 October 2014 at 11:01:30 UTC, John Colvin wrote:On Saturday, 4 October 2014 at 10:38:32 UTC, ketmar via Digitalmars-d-learn wrote:Inheritance works too: //methodLink.d import std.stdio; class Base { void foo() { writeln("From Base"); } } class A : Base { override void foo(); } void main() { Base a = new A; a.foo(); a.Base.foo(); } $ dmd methodLink.d missingMethod.o $ ./methodLink Hello World From BaseOn Sat, 04 Oct 2014 10:27:16 +0000 John Colvin via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:Yes, you can. You just have to get the mangling right. // methodLink.d class A { void foo(); } void main() { auto a = new A; a.foo(); } // missingMethod.d import methodLink; import std.stdio; pragma(mangle, A.foo.mangleof) void foo() { writeln("Hello World"); } $ dmd missingMethod.d -c $ dmd methodLink.d missingMethod.o $ ./methodLink Hello WorldSorry, but that's just not how it works. There is no requirement for the definition of a function to be found in the same compilation unit as it's declaration.is there any possibility to declare *class* *method* in one file and to implement it in another? O_O i doubt so.
Oct 04 2014
On Sat, 04 Oct 2014 11:01:28 +0000 John Colvin via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:On Saturday, 4 October 2014 at 10:38:32 UTC, ketmar via=20 Digitalmars-d-learn wrote:and how about access to class fields? manual mangling is a half-working hack. alas. i really want to have some normal and non-hackish way to separate class definition and class implementation. besides, your trick is faulty, 'cause it misses hidden 'this' parameter. try that: // methodLink.d class A { void foo(int n); } void main () { auto a =3D new A; a.foo(42); } // missingMethod.d import methodLink; import std.stdio; pragma(mangle, A.foo.mangleof) void foo(int n) { writeln("n=3D", n); } it writes gibberish and segfaults.On Sat, 04 Oct 2014 10:27:16 +0000 John Colvin via Digitalmars-d-learn=20 <digitalmars-d-learn puremagic.com> wrote:=20 Yes, you can. You just have to get the mangling right.Sorry, but that's just not how it works. There is no=20 requirement for the definition of a function to be found in=20 the same compilation unit as it's declaration.is there any possibility to declare *class* *method* in one=20 file and to implement it in another? O_O i doubt so.
Oct 04 2014
On Saturday, 4 October 2014 at 11:19:52 UTC, ketmar via Digitalmars-d-learn wrote:On Sat, 04 Oct 2014 11:01:28 +0000 John Colvin via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:good catch. This works for me, but it's probably not portable due to variations in where the hidden this is passed: //methodLink import std.stdio; class Base { int baseVal; void foo(int a) { writeln("baseVal + a: ", baseVal + a); } } class A : Base { int aVal; this(int v) { aVal = v; baseVal = 2*v; } override void foo(int a); } void main() { Base a = new A(42); a.foo(3); a.Base.foo(3); } // missingMethod.d import methodLink; import std.stdio; pragma(mangle, A.foo.mangleof) void foo(int a, A this_) { writeln("aVal + a: ", this_.aVal + a); } $./methodLink aVal + a: 45 baseVal + a: 87 I don't really see the point though. class A { void foo(int a) { Afoo(this, a); } } then declare and define Afoo however you like.On Saturday, 4 October 2014 at 10:38:32 UTC, ketmar via Digitalmars-d-learn wrote:and how about access to class fields? manual mangling is a half-working hack. alas. i really want to have some normal and non-hackish way to separate class definition and class implementation. besides, your trick is faulty, 'cause it misses hidden 'this' parameter. try that: // methodLink.d class A { void foo(int n); } void main () { auto a = new A; a.foo(42); } // missingMethod.d import methodLink; import std.stdio; pragma(mangle, A.foo.mangleof) void foo(int n) { writeln("n=", n); } it writes gibberish and segfaults.On Sat, 04 Oct 2014 10:27:16 +0000 John Colvin via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:Yes, you can. You just have to get the mangling right.Sorry, but that's just not how it works. There is no requirement for the definition of a function to be found in the same compilation unit as it's declaration.is there any possibility to declare *class* *method* in one file and to implement it in another? O_O i doubt so.
Oct 04 2014
On Sat, 04 Oct 2014 15:29:55 +0000 John Colvin via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:I don't really see the point though. =20 class A { void foo(int a) { Afoo(this, a); } } =20 then declare and define Afoo however you like.it's noisy hackery and namespace pollution. sure i can do this and i'm using this trick when it's better to define some methods for class/struct in another module, but i don't like it. inheritance/interfaces is not the best solution sometimes. sure, i can `import()` any text file, but this is not good for separate compilation (and this is why i want this feature in the first place). to make a long story short: i don't like such hacks. ;-) but i'm not yet familiar with compiler internals enough to write a patch.
Oct 04 2014
On Saturday, 4 October 2014 at 15:54:26 UTC, ketmar via Digitalmars-d-learn wrote:On Sat, 04 Oct 2014 15:29:55 +0000 John Colvin via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:It is a little noisy, but really very little. The only extra noise is the call to Afoo. Namespace pollution? In what way would that cause a problem here?I don't really see the point though. class A { void foo(int a) { Afoo(this, a); } } then declare and define Afoo however you like.it's noisy hackery and namespace pollution. sure i can do this and i'm using this trick when it's better to define some methods for class/struct in another module, but i don't like it.
Oct 04 2014
On Sat, 04 Oct 2014 16:52:08 +0000 John Colvin via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:It is a little noisy, but really very little. The only extra=20 noise is the call to Afoo.it's "very little" turns to "alot" with alot of classes with alot of methods. and code readability suffers even from one such hack.Namespace pollution? In what way would that cause a problem here?all this AFoo, BFoo, CFoo, XYZFoo are useless. all they do is polluting namespace, making debug info bigger and processing debug info slower. each unnecessary thing that computer must process is... well, unnecessary. ;-) i'm doing some tricks with debug info -- such as live code instrumentation, and i hate all that 'proxies'. ;-) i again must write code to deal with things that compiler should deal with.
Oct 04 2014
On Saturday, 4 October 2014 at 15:29:57 UTC, John Colvin wrote:On Saturday, 4 October 2014 at 11:19:52 UTC, ketmar via Digitalmars-d-learn wrote:On Sat, 04 Oct 2014 11:01:28 +0000 John Colvin via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:On Saturday, 4 October 2014 at 10:38:32 UTC, ketmar via Digitalmars-d-learn wrote:On Sat, 04 Oct 2014 10:27:16 +0000 John Colvin via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:I don't really see the point though. class A { void foo(int a) { Afoo(this, a); } } then declare and define Afoo however you like.That's hackish, bad and convoluted. And it does not/should not allow one to mess with the private fields of the class, especially if Afoo is defined in another module. And on that matter, a function that is to be provided by another module should be explicitly marked as such in its declaration. Otherwise, I could declare a function, forget to provide its definition, still having the surprise that the code compiles and runs with very strange results because some other module provides a function that just happens to work. Let's not even say how messy this could get with version() where you could disable a function definition by error, in one version, but still have a software that compiles and runs nowhere.
Oct 06 2014
On Monday, 6 October 2014 at 10:10:04 UTC, eles wrote:On Saturday, 4 October 2014 at 15:29:57 UTC, John Colvin wrote:I disagree. It's simple and easy to understand.On Saturday, 4 October 2014 at 11:19:52 UTC, ketmar via Digitalmars-d-learn wrote:On Sat, 04 Oct 2014 11:01:28 +0000 John Colvin via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:On Saturday, 4 October 2014 at 10:38:32 UTC, ketmar via Digitalmars-d-learn wrote:On Sat, 04 Oct 2014 10:27:16 +0000 John Colvin via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:I don't really see the point though. class A { void foo(int a) { Afoo(this, a); } } then declare and define Afoo however you like.That's hackish, bad and convoluted.And it does not/should not allow one to mess with the private fields of the class, especially if Afoo is defined in another module.s/especially/only This is the only genuine problem I can see that requires a language extension. Separating class definition from method definition in to different compilation units doesn't allow access to private members without very nasty hacks.And on that matter, a function that is to be provided by another module should be explicitly marked as such in its declaration. Otherwise, I could declare a function, forget to provide its definition, still having the surprise that the code compiles and runs with very strange results because some other module provides a function that just happens to work.I don't quite follow. Example?Let's not even say how messy this could get with version() where you could disable a function definition by error, in one version, but still have a software that compiles and runs nowhere.
Oct 06 2014
On Monday, 6 October 2014 at 11:54:56 UTC, John Colvin wrote:On Monday, 6 October 2014 at 10:10:04 UTC, eles wrote:On Saturday, 4 October 2014 at 15:29:57 UTC, John Colvin wrote:On Saturday, 4 October 2014 at 11:19:52 UTC, ketmar via Digitalmars-d-learn wrote:On Sat, 04 Oct 2014 11:01:28 +0000 John Colvin via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:On Saturday, 4 October 2014 at 10:38:32 UTC, ketmar via Digitalmars-d-learn wrote:On Sat, 04 Oct 2014 10:27:16 +0000 John Colvin via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:I don't quite follow. Example?Well, in the OP example, imagine that I was trying to compile this module along with another one that simply happened to have a method defined in a way that the linker would have find it. I would have compiled with: dmd app.d app2.d and be unaware what bug I have introduced because I forgot do declare formula() as abstract in the first class.
Oct 06 2014
On Monday, 6 October 2014 at 12:16:14 UTC, eles wrote:On Monday, 6 October 2014 at 11:54:56 UTC, John Colvin wrote:This isn't a problem. You're not going to get the name-mangling right by accident. Even for free functions the module name is mangled in. The only way this can happen is with extern(C) functions, which is because C doesn't mangle it's function names.On Monday, 6 October 2014 at 10:10:04 UTC, eles wrote:On Saturday, 4 October 2014 at 15:29:57 UTC, John Colvin wrote:On Saturday, 4 October 2014 at 11:19:52 UTC, ketmar via Digitalmars-d-learn wrote:On Sat, 04 Oct 2014 11:01:28 +0000 John Colvin via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:On Saturday, 4 October 2014 at 10:38:32 UTC, ketmar via Digitalmars-d-learn wrote:On Sat, 04 Oct 2014 10:27:16 +0000 John Colvin via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:I don't quite follow. Example?Well, in the OP example, imagine that I was trying to compile this module along with another one that simply happened to have a method defined in a way that the linker would have find it. I would have compiled with: dmd app.d app2.d and be unaware what bug I have introduced because I forgot do declare formula() as abstract in the first class.
Oct 06 2014
On Monday, 6 October 2014 at 13:23:55 UTC, John Colvin wrote:On Monday, 6 October 2014 at 12:16:14 UTC, eles wrote:On Monday, 6 October 2014 at 11:54:56 UTC, John Colvin wrote:On Monday, 6 October 2014 at 10:10:04 UTC, eles wrote:On Saturday, 4 October 2014 at 15:29:57 UTC, John Colvin wrote:On Saturday, 4 October 2014 at 11:19:52 UTC, ketmar via Digitalmars-d-learn wrote:On Sat, 04 Oct 2014 11:01:28 +0000 John Colvin via Digitalmars-d-learnThis isn't a problem. You're not going to get the name-mangling right by accident. Even for free functions the module name is mangled in.It is. I could erase the definition of an identical class in another .d file and accidentally leave an orphan definition method therein.The only way this can happen is with extern(C) functions, which is because C doesn't mangle it's function names.This too is a hole. Why to leave holes? I like the "fromage à trous": http://fr.wikipedia.org/wiki/Paradoxe_du_fromage_à_trous But not in my software.
Oct 06 2014
On Monday, 6 October 2014 at 16:02:40 UTC, eles wrote:On Monday, 6 October 2014 at 13:23:55 UTC, John Colvin wrote:Unless I misunderstand you, this can't happen. Class methods are mangled to contain the module name and the class name. I can't think of a way of getting the same mangling and getting a bad substitution without either a) pragma(mangle, ...) or b) you have 2 modules with the same name, containing classes with the same name, which you compile completely separately (to prevent the compiler complaining about the duplication), then link the results together. This would also work for free functions. a) is a deliberate feature. b) has bypassed the compiler completely, there's no way it can know. You're never going to do it by accident.On Monday, 6 October 2014 at 12:16:14 UTC, eles wrote:On Monday, 6 October 2014 at 11:54:56 UTC, John Colvin wrote:On Monday, 6 October 2014 at 10:10:04 UTC, eles wrote:On Saturday, 4 October 2014 at 15:29:57 UTC, John Colvin wrote:On Saturday, 4 October 2014 at 11:19:52 UTC, ketmar via Digitalmars-d-learn wrote:On Sat, 04 Oct 2014 11:01:28 +0000 John Colvin via Digitalmars-d-learnThis isn't a problem. You're not going to get the name-mangling right by accident. Even for free functions the module name is mangled in.It is. I could erase the definition of an identical class in another .d file and accidentally leave an orphan definition method therein.Because it's how C linkage works and if we're using extern(C), it means we want C linkage. That's the point of extern(C).The only way this can happen is with extern(C) functions, which is because C doesn't mangle it's function names.This too is a hole. Why to leave holes?
Oct 06 2014
On Mon, 06 Oct 2014 11:54:55 +0000 John Colvin via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:I disagree. It's simple and easy to understand.and hackish.This is the only genuine problem I can see that requires a=20 language extension. Separating class definition from method=20 definition in to different compilation units doesn't allow access=20 to private members without very nasty hacks.no hacks needed. =3D=3D pkg.classdef.d =3D=3D module pkg.classdef; class A { private: int hiddenField; int bar (); } =3D=3D pkg.othermodule.d =3D=3D=3D module pkg.othermodule; import pkg.classdef; // this imlements A.bar() declared in pkg.classdef: implementation(A) int bar () { return this.hiddenField; } compiler is perfectly able to put A.bar() implementation in the scope of A, and then A.bar can access anything in A. it's the same as declaring bar() in class definition.
Oct 06 2014
On Monday, 6 October 2014 at 12:36:41 UTC, ketmar via Digitalmars-d-learn wrote:On Mon, 06 Oct 2014 11:54:55 +0000 John Colvin via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:D is very amenable to slightly hackish code.I disagree. It's simple and easy to understand.and hackish.This is the only genuine problem I can see that requires a language extension. Separating class definition from method definition in to different compilation units doesn't allow access to private members without very nasty hacks.no hacks needed.I meant that without a language change, one does need hacks.== pkg.classdef.d == module pkg.classdef; class A { private: int hiddenField; int bar (); } == pkg.othermodule.d === module pkg.othermodule; import pkg.classdef; // this imlements A.bar() declared in pkg.classdef: implementation(A) int bar () { return this.hiddenField; } compiler is perfectly able to put A.bar() implementation in the scope of A, and then A.bar can access anything in A. it's the same as declaring bar() in class definition.That would be nice, although personally I'd prefer int A.bar() { return this.hiddenField; } as it's less verbose and would be familiar to c++ programmers.
Oct 06 2014
On Mon, 06 Oct 2014 15:44:34 +0000 John Colvin via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:D allows to write hackish code, and it's good. but if we can provide a way to write less hackish code, it's good and preferable, i think. ;-)D is very amenable to slightly hackish code.I disagree. It's simple and easy to understand.and hackish.i see.no hacks needed.I meant that without a language change, one does need hacks.That would be nice, although personally I'd prefer =20 int A.bar() { return this.hiddenField; } =20 as it's less verbose and would be familiar to c++ programmers.i was trying to not change grammar, that's why i invented that horribly-looking implementation attribute. this way the code is still marked as a hack, but "officially endorsed" hack. besides, attribute allows to use code blocks: implementation(A) { int foo () { ... } void bar () { ... } } or even: implementation(A): int foo () { ... } void bar () { ... } sure, it has it's own pack of problems: implementation(A) { implementation(B) { // I'M LOST! } } but we can have both! ;-)
Oct 06 2014
On Monday, 6 October 2014 at 15:44:36 UTC, John Colvin wrote:On Monday, 6 October 2014 at 12:36:41 UTC, ketmar via Digitalmars-d-learn wrote:So, you admit it is a hack! Gotcha!On Mon, 06 Oct 2014 11:54:55 +0000 John Colvin via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:D is very amenable to slightly hackish code.I disagree. It's simple and easy to understand.and hackish.This is the only genuine problem I can see that requires a language extension. Separating class definition from method definition in to different compilation units doesn't allow access to private members without very nasty hacks.no hacks needed.I meant that without a language change, one does need hacks.
Oct 06 2014
On Monday, 6 October 2014 at 16:04:02 UTC, eles wrote:On Monday, 6 October 2014 at 15:44:36 UTC, John Colvin wrote:In order to get access to private variables from another compilation unit, yes, you need some nasty hackiness. I haven't presented such a hack though.On Monday, 6 October 2014 at 12:36:41 UTC, ketmar via Digitalmars-d-learn wrote:So, you admit it is a hack! Gotcha!On Mon, 06 Oct 2014 11:54:55 +0000 John Colvin via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:D is very amenable to slightly hackish code.I disagree. It's simple and easy to understand.and hackish.This is the only genuine problem I can see that requires a language extension. Separating class definition from method definition in to different compilation units doesn't allow access to private members without very nasty hacks.no hacks needed.I meant that without a language change, one does need hacks.
Oct 06 2014
On Monday, 6 October 2014 at 19:03:13 UTC, John Colvin wrote:On Monday, 6 October 2014 at 16:04:02 UTC, eles wrote:On Monday, 6 October 2014 at 15:44:36 UTC, John Colvin wrote:On Monday, 6 October 2014 at 12:36:41 UTC, ketmar via Digitalmars-d-learn wrote:On Mon, 06 Oct 2014 11:54:55 +0000 John Colvin via Digitalmars-d-learn <digitalmars-d-learn puremagic.com>In order to get access to private variables from another compilation unit, yes, you need some nasty hackiness. I haven't presented such a hack though.I know. Was not serious.
Oct 06 2014
On Saturday, 4 October 2014 at 10:27:18 UTC, John Colvin wrote:On Saturday, 4 October 2014 at 04:02:46 UTC, eles wrote:This seem to allow an entire class of problems, by linking against long-time forgotten functions...On Friday, 3 October 2014 at 15:47:33 UTC, John Colvin wrote:Sorry, but that's just not how it works. There is no requirement for the definition of a function to be found in the same compilation unit as it's declaration. // a.d void foo(); void main() { foo(); } // b.d import std.stdio; void foo() { writeln("Hello World"); } $ ls a.d b.d $ dmd b.d -c $ ls a.d b.d b.o $ dmd a.d b.o $ ls a a.d a.o b.d b.o $ ./a Hello WorldOn Friday, 3 October 2014 at 15:44:16 UTC, eles wrote:Thanks, but still. The compiler shall not let that code pass down to the linker. It has everything it needs to not do that, or it shall have. Linker errors shall be simply because the libraries are not in place (either not installed, either linking path not correctly configured, either broken versions of those libraries).class ShapeSurface(T) { public: int formula();that means you have a definition of formula elsewhere (which the linker tries to find, but obviously fails. What you want is class ShapeSurface(T) { public: abstract int formula();
Oct 04 2014