Re: prolog and epilog code
On Tuesday, 2 August 2016 at 20:28:51 UTC, Rufus Smith wrote: On Tuesday, 2 August 2016 at 18:34:49 UTC, Steven Schveighoffer wrote: On 8/2/16 2:25 PM, Rufus Smith wrote: So, something funky is going on. Any ideas? phobos is not being resolved. I don't use visualD, so I'm not sure what the issue is, it's probably a compiler or linker ordering issue. -Steve Um, but it works as long as I a main function! So while it might be something weird with visualD, it's probably something more related to dmd(flag or something). Cause I am using phobo's... that is, unless it does not link in phobo's if there is no D main file(trying to be smart). If I link in phobos manually most of the errors go away, I'm left with" main.obj : error LNK2019: unresolved external symbol "int __cdecl rt_init(void)" (?rt_init@@YAHXZ) referenced in function main main.obj : error LNK2019: unresolved external symbol "void __cdecl Dmain(void)" (?Dmain@@YAXXZ) referenced in function main phobos64.lib(sections_win64_2317_4e2.obj) : error LNK2019: unresolved external symbol _deh_beg referenced in function _D2rt14sections_win6412SectionGroup8ehTablesMxFNdZAyS2rt15deh_win64_posix9FuncTable (const(@property immutable(rt.deh_win64_posix.FuncTable)[] function()) rt.sections_win64.SectionGroup.ehTables) phobos64.lib(sections_win64_2317_4e2.obj) : error LNK2019: unresolved external symbol _deh_end referenced in function _D2rt14sections_win6412SectionGroup8ehTablesMxFNdZAyS2rt15deh_win64_posix9FuncTable (const(@property immutable(rt.deh_win64_posix.FuncTable)[] function()) rt.sections_win64.SectionGroup.ehTables) This mainly seems that the d code is not being linked with the c code. But I guess this is all on VisualD's end since since it seems just to be the command line not getting the correct stuff, for some oddball reasons.
Re: prolog and epilog code
On Tuesday, 2 August 2016 at 18:34:49 UTC, Steven Schveighoffer wrote: On 8/2/16 2:25 PM, Rufus Smith wrote: So, something funky is going on. Any ideas? phobos is not being resolved. I don't use visualD, so I'm not sure what the issue is, it's probably a compiler or linker ordering issue. -Steve Um, but it works as long as I a main function! So while it might be something weird with visualD, it's probably something more related to dmd(flag or something). Cause I am using phobo's... that is, unless it does not link in phobo's if there is no D main file(trying to be smart).
Re: prolog and epilog code
On Tuesday, 2 August 2016 at 17:25:21 UTC, Steven Schveighoffer wrote: On 8/2/16 1:04 PM, Rufus Smith wrote: On Tuesday, 2 August 2016 at 16:30:08 UTC, Adam D. Ruppe wrote: On Tuesday, 2 August 2016 at 16:21:07 UTC, Rufus Smith wrote: How does one use C main? extern C? extern(C) int main() should do it It doesn't seem to be that easy! https://wiki.dlang.org/Runtime_internals This is just explaining how the runtime currently works, not how you should override it. It's really easy actually. Example: $ cat main.c #include extern int rt_init(); extern void d_func(); int main(int argc, char *argv[]) { printf("hello from C!\n"); rt_init(); printf("done initializing runtime\n"); d_func(); } $ cat dmain.d extern(C) void d_func() { import std.stdio; writeln("hello from D!"); } shared static this() { import std.stdio; writeln("doing some pre-run init!"); } $ gcc -c main.c $ dmd dmain.d main.o $ ./dmain hello from C! doing some pre-run init! done initializing runtime hello from D! -Steve When I do this in my project and try to link in the lib or obj created from the C project, I get "entry point must be defined" error. I tried to add both to the "command line". If I don't have a main function in D, I get all kinds of unresolved externals. Not sure why, but it seems to not import in the runtime when there is no main defined. Basically I created a side C++ project, copied your code in to the main.cpp. I then added the obj file to the linker command line path. Then I get the missing entry point error. It is very similar to yours, just using VisualD and windows. Seems like it would be easier just to create a wrapper process and use shared memory to transfer data between them ;/ For example, if I just create a new D project. Add a new cpp file and paste your C code in, paste the D code in the empty D file, and try to compile, I get: main.cpp main.obj : error LNK2019: unresolved external symbol "int __cdecl rt_init(void)" (?rt_init@@YAHXZ) referenced in function main main.obj : error LNK2019: unresolved external symbol "void __cdecl d_func(void)" (?d_func@@YAXXZ) referenced in function main CMain.obj : error LNK2001: unresolved external symbol _D14TypeInfo_Const6__vtblZ CMain.obj : error LNK2019: unresolved external symbol _d_throwc referenced in function _D3std9exception143__T12errnoEnforceTiVAyaa54_423a5c444c616e675c646d64325c77696e646f77735c62696e5c2e2e5c2e2e5c7372635c70686f626f735c7374645c737464696f2e64Vmi2543Z12errnoEnforceFNfiLAyaZi (@safe int std.exception.errnoEnforce!(int, "dmd2\windows\bin\..\..\src\phobos\std\stdio.d", 2543uL).errnoEnforce(int, lazy immutable(char)[])) CMain.obj : error LNK2001: unresolved external symbol _D12TypeInfo_Aya6__initZ CMain.obj : error LNK2019: unresolved external symbol _D3std3utf12isValidDcharFNaNbNiNfwZb referenced in function _D3std5stdio4File17LockingTextWriter10__T3putTwZ3putMFNbNiNfwZv CMain.obj : error LNK2019: unresolved external symbol _D3std9exception14ErrnoException6__ctorMFNeAyaAyamZC3std9exception14ErrnoException (@trusted std.exception.ErrnoException std.exception.ErrnoException.__ctor(immutable(char)[], immutable(char)[], ulong)) referenced in function _D3std9exception143__T12errnoEnforceTiVAyaa54_423a5c444c616e675c646d64325c77696e646f77735c62696e5c2e2e5c2e2e5c7372635c70686f626f735c7374645c737464696f2e64Vmi2543Z12errnoEnforceFNfiLAyaZi (@safe int std.exception.errnoEnforce!(int, "dmd2\windows\bin\..\..\src\phobos\std\stdio.d", 2543uL).errnoEnforce(int, lazy immutable(char)[])) CMain.obj : error LNK2019: unresolved external symbol _aApplycd1 referenced in function _D3std5stdio4File17LockingTextWriter12__T3putTAyaZ3putMFNfAyaZv (@safe void std.stdio.File.LockingTextWriter.put!(immutable(char)[]).put(immutable(char)[])) CMain.obj : error LNK2019: unresolved external symbol _D3std5stdio8__assertFiZv (void std.stdio.__assert(int)) referenced in function _D3std5stdio4File17LockingTextWriter10__T3putTwZ3putMFNbNiNfwZv CMain.obj : error LNK2019: unresolved external symbol _D3std5stdio4File17lockingTextWriterMFNfZS3std5stdio4File17LockingTextWriter (@safe std.stdio.File.LockingTextWriter std.stdio.File.lockingTextWriter()) referenced in function _D3std5stdio16__T7writelnTAyaZ7writelnFNfAyaZv (@safe void std.stdio.writeln!(immutable(char)[]).writeln(immutable(char)[])) CMain.obj : error LNK2001: unresolved external symbol _D3std5stdio12__ModuleInfoZ CMain.obj : error LNK2019: unresolved external symbol _D3std5stdio13trustedStdoutFNdNeZS3std5stdio4File (@property @trusted std.stdio.File std.stdio.trustedStdout()) referenced in function _D3std5stdio16__T7writelnTAyaZ7writelnFNfAyaZv (@safe void std.stdio.writeln!(immutable(char)[]).writeln(immutable(char)[])) CMain.obj : error LNK2019: unresolved external symbol _D3std3utf6toUTF8FNaNbNiNfNkJG4awZAa referenced in function _D3std5stdio4File17LockingTextWriter10__T3putTwZ3putMFNbNiNfwZv CMain.obj : error LNK2019: unresolved external
Re: prolog and epilog code
On Tuesday, 2 August 2016 at 16:30:08 UTC, Adam D. Ruppe wrote: On Tuesday, 2 August 2016 at 16:21:07 UTC, Rufus Smith wrote: How does one use C main? extern C? extern(C) int main() should do it It doesn't seem to be that easy! https://wiki.dlang.org/Runtime_internals If I do this then I get lots of missing imports(the D runtime). import std.stdio; import core.runtime; private alias extern(C) int function(char[][] args) MainFunc; extern int _d_run_main(int argc, char **argv, MainFunc mainFunc); extern(C) void main(int argc, char **argv) { rt_init(); _d_run_main(argc, argv, &_main); rt_term(); } extern(C) int _main(char[][] args) { return 0; } Or even using the code from the wiki, I get unresolved externals. Mainly the druntime like stuff(typeinfo, aa stuff, etc...).
Re: prolog and epilog code
On Tuesday, 2 August 2016 at 11:37:05 UTC, Steven Schveighoffer wrote: On 8/1/16 9:24 PM, Rufus Smith wrote: Can one add code that executes before the GC and any memory is normally allocated(even static) and after all of it was suppose to be released? Of course! You just have to modify druntime :) That doesn't sound like fun. Why doesn't D add a hook for program level static this(we have module level, need something more)? One thing you can do instead is compile without a D main function, and use C main, initialize the runtime manually. Then you can put your measurement code around the runtime initialization and termination. How does one use C main? extern C? Or do I have to actually write C code?
prolog and epilog code
Can one add code that executes before the GC and any memory is normally allocated(even static) and after all of it was suppose to be released? A sort of static this for the whole app. I would like to monitor the memory of the app to make sure that the total memory before and after is equal. I use my own memory routines but would like something where I can write out the information after all destructors have been called. I have malloc and free wrapped and simply add the total memory used and released. These, of course, should be the same *after* program termination. But, I can't wait that long ;)
Re: Cannot compare object.opEquals is not nogc
On Monday, 25 July 2016 at 12:24:53 UTC, Steven Schveighoffer wrote: On 7/23/16 5:44 PM, Rufus Smith wrote: [...] Again, I want to stress that Object.opEquals has been around since early D1 days, @nogc is only a few years old, it was not a wrong decision. @nogc cannot be added without breaking code, and even if you could, it's not correct for opEquals. The issue is one of design, Object should not define which attributes are acceptable on all objects, that should be up to the class designer. The solution is to deprecate and remove all convenience functions from Object. [...] This is an extreme solution for a minor problem. Minor for you... not for everyone. Some people despise the GC and try to write nogc code. For them it is not extreme. It is extreme for you because you are on the other side. Please don't treat your side as the only side.
Re: Cannot compare object.opEquals is not nogc
On Saturday, 23 July 2016 at 13:18:03 UTC, Rufus Smith wrote: Trying to compare a *ptr value with a value in nogc code results in the error: Error: @nogc function '...' cannot call non-@nogc function 'object.opEquals' Shouldn't object opEquals be marked? So, I need to compare two objects in a no-gc context? How to do this? There are several checks to be done? Memory compare good enough? (not if opEquals is defined for structs, etc...) Unfortunately, regardless of what some people say, There is a need to compare objects in a nogc context... I have the case for one. e.g., I have a nogc container and a remove(T obj). I can't search for obj and remove it because opEquals is not marked nogc. So I need an alternative that is somewhat robust.
Re: Modules
NM, ignore. Seems it was something else going on. Although, if you know how how dmd resolves this stuff exactly, it would be nice to know. Does it just use the module names regardless of path or does the path where the module is located have any play(assuming they are properly passed to the compiler).
Modules
How do module names and actual folder paths relate? For my own libraries, I use the file path as module name, more or less. e.g., module foo.bar.x; is in folder foo\bar. I imported some external lib that has it's own layout, but I wanted to incorporate it in to my lib, so I stuck it in a sub folder. DMD complains though. I can't change the source because that is brittle, but I don't want it to be sitting in Root because that is messy. foo bar x baz y baz.d(package) where y is the external lib I imported. It uses it's own layout scheme though. I tried to use a package and import the modules as anyone would, then I could just import the package, but that doesn't work either. module foo.baz; public import y; So, all I want to do is use someone elses d files and put them in a subdir without having to modify their files to get it to work(to be able to import them like anything else). Is this another impossibility?
Re: Cannot compare object.opEquals is not nogc
On Saturday, 23 July 2016 at 22:48:07 UTC, Lodovico Giaretta wrote: On Saturday, 23 July 2016 at 21:44:05 UTC, Rufus Smith wrote: On Saturday, 23 July 2016 at 17:27:24 UTC, Lodovico Giaretta wrote: - we trust what we are doing: e.g. we cannot mark a thing @nogc, but we know it is and the profiler confirms that no allocation happens, so we are happy; our aim is having code that doesn't freeze because of collections, and not marking code @nogc. This is bad. It only creates a faulty foundation. The whole point of nogc is to enforce nogc behavior. If you don't use it your not enforcing anything and then things slip by only to create problems later. This mentality is completely wrong and leads to decay. While you are right on this, we must be pragmatical: we currently do not enforce that pointers point to valid memory locations, that private members are not accessed outside the module with tricky arithmetics, we have tons of things that work by convention, because the compiler simply can't check them all and some are even intrinsically uncheckable. In this environment of "code by trust", @nogc is the least of the problems, also because, I insist, it can be checked with the profiler, or you can plug a custom GC to druntime that asserts every time you try to call its functions (work is being made to make the GC independent and pluggable). This is exactly why we are discussing this right now, because someone decided that it was ok to ignore other use cases which eventually turn out to be quite important. Well, I think that deciding that opXXX must always be @nogc, ignoring other use cases that may need the GC, is blatantly wrong. By asking that Object.opXXX be @nogc, you are making the error the error you said others made. This just isn't right. What your saying is that because someone screwed up, we must live with the screw up and build everyone around the screw up. This mentality is why everyone is so screwed up in the first place, do you not see that? And I think you really have a misconception about the GC vs nogc. One can rewrite GC code, such as an GC based opEquals, without limitations. They can allocate on the stack, use malloc and free when done, etc. opEquals generally doesn't have state. So you it is possible to around around. It's probably always possible to rewrite a GC opEquals to use nogc without too much difficulty. BUT, it is impossible to use a GC opEquals in nogc code! This means there is no work around. What you claim is that we accept the impossiblity(which makes nogc useless) just to avoid having to rewrite some GC opEquals code. We can't rewrite the nogc side, it's set in stone. We are screwed from the start when we attempt to do nogc code because at some point we will have to do comparisons. It's the same problem with purity and any other transitive relationship. All "workarounds" are just as limited because basically we added the relationship if A is nogc and A uses B, then B must be nogc. Yet, we start with B is GC. Hence we never ever have A use B, because A's can only use nogc. To see it simpler, What if everything in D was GC based. All code was marked GC(even statements, types, etc). Do you agree that nogc would be absolutely useless? We couldn't build up anything because we couldn't include any code. This is the extreme case. Conversely, if everything was built up using nogc, we could write GC based code just fine, could we not? Therefore, claiming that we stay with GC based code just prevents using more and more nogc code. The more GC based code D gets, the less useful nogc gets and we are back were we started. Since nogc is more critical in the foundational layers, as it affects everything built on it, all core features should be nogc. This way, the user isn't can decide when to break away from the GC code, which will only affect everything after that point. This is a one way street, pretending it is two way only enriches the lawyers and eventually makes everyone unhappy. Making the D dependent on the GC was a mistake that many wasted man hours will go in to trying to unravel. Trying to carry on this mistake just wastes more hours. I understand that it is a mess, but it got that way from the mistake in the first place, not from trying to undo the mistake(which is illogical because there would be no nogc if there wasn't a gc in the first place). I also understand that there is some desire to keep things "backwards compatible". This is also a mistake, not only does it prolong the pain and suffering but is irrational. 1. A fork can be made. Those people that have based their code on the GC can continue using an older version. Their code works at that point, does it not? So just stop going down that dead end path. They have what they need, it's not like they will lose anything(virtually nothing except in most cases). Moving in the correct direction is always better, regardless of
Re: Cannot compare object.opEquals is not nogc
On Saturday, 23 July 2016 at 17:27:24 UTC, Lodovico Giaretta wrote: On Saturday, 23 July 2016 at 17:04:42 UTC, Jonathan Marler wrote: On Saturday, 23 July 2016 at 16:46:20 UTC, Jonathan Marler wrote: [...] Actually Im going to disagree with myself. This technique actually wouldn't work with virtual methods:) I don't think we have the big problems with @nogc that people points out. I mean, we cannot decide that specific methods or opXXX must always be @nogc. That's too restrictive. So, what we need to do is: - use templates: with them, we can have our algorithms be @safe when applied to @safe types, @nogc when applied to @nogc types, and so on; for example, instead of taking a specific delegate type, we shall always accept a generic type, and use traits to guarantee it is some delegate; in this way, we can accept @safe delegate and propagate @safety to our algorithm, or accept @system and have our algorithm usable in @system code; same with @nogc et al. - when we use virtual methods, we are giving up all compiler-checked attributes; in this situation we have two options: - we trust what we are doing: e.g. we cannot mark a thing @nogc, but we know it is and the profiler confirms that no allocation happens, so we are happy; our aim is having code that doesn't freeze because of collections, and not marking code @nogc. This is bad. It only creates a faulty foundation. The whole point of nogc is to enforce nogc behavior. If you don't use it your not enforcing anything and then things slip by only to create problems later. This mentality is completely wrong and leads to decay. This is exactly why we are discussing this right now, because someone decided that it was ok to ignore other use cases which eventually turn out to be quite important. If, say, D was built without the GC, then adding the GC would be much easier and more logical than what has been done, which is built with GC and trying to remove it. - we must have @nogc (or @whatever): then we know we cannot use certain classes, because they are definitely @nogc; so we cast the objects we get to the classes/interfaces that we know are @nogc (and are marked as such), and then our code is @nogc; as you see, you don't need Object to have @nogc methods; you only need the specific classes you use have it; if you want to work on generic objects, and as such cannot do specific casts, then you should definitely be using templates. The only real problems I found till now are: - some things in Phobos that shall be @nogc are not; they shall be refactored to have that attribute (but this is not always easy and requires time) - the interface IAllocator is mostly used with @nogc allocators, but cannot have the said attribute (as I explained above, it must not restrict the possibility of allocators); it shall have a sub-interface NoGCAllocator, so that code can accept a @nogc allocator parameter without using templates (of course templates are fine, and are what we use now, but if everyone uses templates, why have IAllocator in the first place? IMHO we must have or both or none). Templates are not the end all be all. They don't allow for run-time polymorphism, which is an important aspect of software. What we should have is that when something is added or removed we are 100%(or close as we can get) that the feature is correct and causes no side effects. D's GC causes side effects because it was assumed that there would not be any. Now the future is hear and it's up to us to try and unravel the mess the past created. It's always best to just do it right in the first place, it saves everyone from the headache. DMD should probably be branched, and all GC stuff removed, then built back up to have the proper features that the GC version has. I think someone has essentially done this on their own, but never built it up to full capacity.
Re: Cannot compare object.opEquals is not nogc
On Saturday, 23 July 2016 at 17:23:37 UTC, Marco Leise wrote: Am Sat, 23 Jul 2016 13:18:03 + schrieb Rufus Smith: Trying to compare a *ptr value with a value in nogc code results in the error: Error: @nogc function '...' cannot call non-@nogc function 'object.opEquals' Shouldn't object opEquals be marked? The only situation that you can work around is if the 'object' is actually known to be one of your @nogc objects. Then you can simply downcast before calling opEquals. It's certainly limiting, but just an artifact of OOP and I can assure you that making D usable without GC has been high on the priority list (for an community driven open-source project anyways). Phobos got reworked to get rid of unnecessary GC allocations and Andrei Alexandrescu contemplated making object's methods @nogc at one point. If you need a restricted object hierarchy, you'll have to write a new "NoGcObject" base class. opEquals would still take "object", though you can avoid a dynamic cast by writing: (cast(NoGcObject)cast(void*)obj).someMethod(); The cast to void* prior to the downcast drops the class type information and a dynamic cast becomes a static cast. I am trying to write some general code that works on arbitrary types. I need to compare, obviously, as that is relatively basic thing on objects. About the only half-ass solution I can think of is to use introspection and require the type to support a nogc version of Equals. Of course, this only passes the buck. The problem is, D was designed with GC in mind, which was flawed from the get go and now trying to undo the tangled mess leads to "We can't do that because it's not backwards compatible". So one crack leads to another to another. From what I gather, this isn't just a problem with nogc but many "after the fact enhancements" that don't work the way they should because of lack of foresight on the designers of D.
Re: Cannot compare object.opEquals is not nogc
On Saturday, 23 July 2016 at 14:15:03 UTC, Lodovico Giaretta wrote: On Saturday, 23 July 2016 at 13:18:03 UTC, Rufus Smith wrote: Trying to compare a *ptr value with a value in nogc code results in the error: Error: @nogc function '...' cannot call non-@nogc function 'object.opEquals' Shouldn't object opEquals be marked? If object.opEquals is marked @nogc, than all D classes must implement it as @nogc, because (of course) you cannot override a @nogc method with a not-@nogc one (while the opposite is possible, of course). So marking it @nogc is not only a big breaking change, but also very limiting. Um, this isn't right. GC code can always call non-gc code. If you mark opEquals nogc, it breaks nothing except implementations of opEquals that use the GC. GC code can still call it nogc opequals, it only enforces opEquals code to avoid the GC itself, which isn't a terrible thing. What is terrible is that nogc code can never have any equality comparisons! It is impossible unless one manually tests them, but how? Every method would be brittle. Do a memory test? compare element by element? One can't predict what to do. So, you are trying off laziness to break nogc. As it stands, if nogc code can't compare equality, it is broken and useless. Why put it in the language then? struct S(T) { @nogc void test(T t1, T t2) { if (t1 == t2) return true; return false; } } Broke! Even if opEquals of T does not use any GC we can't write test to be nogc, which means we can't have S be nogc or anything that depends on S that is nogc. This must be a dirty trick played by the implementors of nogc to keep everyone on the gc nipple? Equality comparison is more fundamental than the GC in programming. There is no fundamental reason why equality comparison depends on the GC. All I can hope for now is that there is a robust way to compare that I can use that is marked nogc. Else all my nogc code is broke. I guess one has this problem with all opOp's!
Cannot compare object.opEquals is not nogc
Trying to compare a *ptr value with a value in nogc code results in the error: Error: @nogc function '...' cannot call non-@nogc function 'object.opEquals' Shouldn't object opEquals be marked?
Re: Building phobos GDC
On Friday, 22 July 2016 at 19:52:59 UTC, Lodovico Giaretta wrote: On Friday, 22 July 2016 at 18:30:13 UTC, Rufus Smith wrote: Trying to compile code that uses GDC, had to import phobos files from dmd in to project since they are not in the GDC's phobo lib(the core.sys.windows stuff). Almost all the errors are related to stuff like PALETTEENTRY* peNew() return { return _peNew.ptr; } Does that even make sense? I'll add that, in general, it's a bad idea to mix the libraries of the various compilers. In fact, the library has the same release cycle as the frontend, and is specific to the frontend version it comes with. GDC is several frontend versions behind DMD, so GDC cannot support the new features / characteristics of the recent DMD libraries. You should always use a Phobos version as old as the frontend of the compiler you're using. I don't agree with this. The versions are too far out of sync. It is better to test the different versions together because they are not consistent. As I yet I can neither use GDC or LDC because they don't compile the code that works with DMD. This is a problem with those compilers. If one could guarantee that the oldest compiler was always compatible, eventually(reasonably), with the newest one, it would be a different story. But bugs creep in. I'd rather work with the reference compiler, the actual one the language is based off of, rather than work with one that is not even guaranteed to be maintained properly. With dmd, I know exactly what I'm getting and I only bother with the other compilers due to performance, which is not priority when developing. Hence, I hope that the other compilers are up to speed once I am finished with developing. This is a risk, but no more than expecting those compilers to eventually be updated. Given that the maintenance of LDC and GDC are rather low compared to DMD, I'd rather stick with DMD.
Building phobos GDC
Trying to compile code that uses GDC, had to import phobos files from dmd in to project since they are not in the GDC's phobo lib(the core.sys.windows stuff). Almost all the errors are related to stuff like PALETTEENTRY* peNew() return { return _peNew.ptr; } Does that even make sense?
Re: union initalization
On Friday, 22 July 2016 at 02:08:06 UTC, Ali Çehreli wrote: On 07/21/2016 06:48 PM, Rufus Smith wrote: > I would like to combine two types > > > template Foo(A, B = 4) > { > union > { > byte b = B; > int a = A << 8; > } > } > > This packs a and b together in to an int bytes, saving an int(rather > than storing a and b in an int each) and makes it easier to access. Bitfields may actually be useful in this case: https://dlang.org/phobos/std_bitmanip.html#.bitfields They don't allow default assignment though? > I get an error about overlapping default initialization. They don't > actually overlap in this case because of the shift. The following at least compiles: struct Foo(int A, byte B = 4) { union { byte b = void; int a = void; uint __both = (A << 8) | B; } } void main() { auto f = Foo!(42)(); } Ali Maybe... I don't like extra member. Bitfields seem like it would be the best way but I require default initialization. I want to hide as details of the work on unpacking as possible.
union initalization
I would like to combine two types template Foo(A, B = 4) { union { byte b = B; int a = A << 8; } } This packs a and b together in to an int bytes, saving an int(rather than storing a and b in an int each) and makes it easier to access. I get an error about overlapping default initialization. They don't actually overlap in this case because of the shift.
Dynamic code generation
Does D offer any solutions to generate code dynamically? I would like to order based on optimal strategies. This requires effectively hard coding the execution path. A simple example, if (x == true) foo(); else bar(); can be recoded to be foo() or bar() while x is fixed, in my case x is fixed for long periods and therefor the check is unnecessary. I also know when x changes in all cases. This is just a simple example, of course. I would not want to resort to assembly programming to accomplish this.
Re: Template arguments produce unidentified identifier
On Wednesday, 20 July 2016 at 01:48:31 UTC, Adam D. Ruppe wrote: Take a read of this: http://stackoverflow.com/a/32621854/1457000 The short of it is don't mixin stringof. Instead, mixin the actual template itself. The functionLinkage might need to be string, but the types should remain literal. So try this: mixin("alias Func = extern("~functionLinkage!Q~") (ReturnType!Q) function (Erase!(Parameters!Q));"); or something like that - don't concatenate strings of those, just make the string itself still say ReturnType!Q etc when you mix in. Then the scope will be correct. Thanks, it did work with some modification: mixin("alias Func = extern("~functionLinkage!Q~") ReturnType!Q function(Erase!(Parameters!Q));"); No parenthesis around ReturnType or strange errors happen.
Re: Template arguments produce unidentified identifier
If it's not clear, I have to import the proper identifiers but every use of the template would require the user to add their import. Obviously not the way to go.
Template arguments produce unidentified identifier
I have complex template that uses a mixin to solve some problems. The mixin produces the error. I thought template's were added in to the scope of the call? I guess the mixin is inserted before this happens. That isn't good ;/ Here is one place the error happens mixin("alias Func = extern("~functionLinkage!Q~") "~(ReturnType!Q).stringof~" function"~(Erase!(Parameters!Q)).stringof~";"); The mixin is required to get the proper linkage, as no other method has been found to do that. Everything works with built in types. I saw somewhere that vibe.d had some way around this but the links are dead.
Re: Allowing "fall through" of attributes
On Tuesday, 19 July 2016 at 17:10:35 UTC, Lodovico Giaretta wrote: On Tuesday, 19 July 2016 at 17:05:55 UTC, Rufus Smith wrote: On Tuesday, 19 July 2016 at 16:59:48 UTC, Lodovico Giaretta wrote: On Tuesday, 19 July 2016 at 16:50:56 UTC, Rufus Smith wrote: On Tuesday, 19 July 2016 at 16:09:38 UTC, Lodovico Giaretta wrote: [...] But this doesn't create a function with all the attributes of the original? Just one that has the same return type and parameters. What if Fun is pure or extern(C) or some other attributes? I'd like to create a function that is exactly the same in all regards as the original. Sorry, I misunderstood your question. With the method I showed you, if the function is @safe, pure, @nogc or nothrow, foo will infer those attributes. But only if the operations you do in foo (apart from calling bar) are themselves @safe, pure, @nogc or nothrow. For other things, like extern(C), I don't think there's a simple solution; but I'm not an expert, so I hope someone else will give you a better answer. What is strange is I cannot even pass an extern(C) function to foo. void foo(R, A...)(R function(A) bar); extern(C) void bar(); foo() fails. Remove extern and it passes. I have not figured out how to allow for extern(C) functions to be passed. That's because an extern function must be called with a different code. So it cannot be cast to a non-extern(C) function pointer, which is what your foo accepts. If you follow my advice, and make the entire function type a parameter of foo, then foo will at least accept your extern(C) function, but it will not be extern(C) itself. I don't want it to be cast to a non-extern function. What I want to do is create the exact same type of function that is passed to the template except modify the arguments. If I use a general parameter for the function, it accepts extern(C), but I can't construct a function with it. mixin("alias F = extern("~functionLinkage!Q~") "~(ReturnType!Q).stringof~" function"~(Parameters!Q).stringof~";"); gives me a type that looks to be what I want but I can't really use it unless I want to declare the function that does the work inside foo as mixin string. One can't do extern(functionLinkage!Q) void baz() to create baz with the proper linkage ;/ It looks like I might have to go the mixin way ;/ Going to be messy ;/
Re: Allowing "fall through" of attributes
On Tuesday, 19 July 2016 at 16:59:48 UTC, Lodovico Giaretta wrote: On Tuesday, 19 July 2016 at 16:50:56 UTC, Rufus Smith wrote: On Tuesday, 19 July 2016 at 16:09:38 UTC, Lodovico Giaretta wrote: [...] But this doesn't create a function with all the attributes of the original? Just one that has the same return type and parameters. What if Fun is pure or extern(C) or some other attributes? I'd like to create a function that is exactly the same in all regards as the original. Sorry, I misunderstood your question. With the method I showed you, if the function is @safe, pure, @nogc or nothrow, foo will infer those attributes. But only if the operations you do in foo (apart from calling bar) are themselves @safe, pure, @nogc or nothrow. For other things, like extern(C), I don't think there's a simple solution; but I'm not an expert, so I hope someone else will give you a better answer. What is strange is I cannot even pass an extern(C) function to foo. void foo(R, A...)(R function(A) bar); extern(C) void bar(); foo() fails. Remove extern and it passes. I have not figured out how to allow for extern(C) functions to be passed.
Re: How to get the "this" ptr of a lambda inside the lambda?
On Tuesday, 19 July 2016 at 16:58:12 UTC, Steven Schveighoffer wrote: On 7/19/16 12:52 PM, Rufus Smith wrote: On Tuesday, 19 July 2016 at 15:58:49 UTC, Steven Schveighoffer wrote: [...] Yes, but then this = null. I matters not for my use case. 'this' is not null in either case. There is no 'this'. Please stop saying that: https://en.wikipedia.org/wiki/This_(computer_programming) this is more general than you think.
Re: How to get the "this" ptr of a lambda inside the lambda?
On Tuesday, 19 July 2016 at 15:58:49 UTC, Steven Schveighoffer wrote: On 7/19/16 11:25 AM, Rufus Smith wrote: [...] I think what Mike may be alluding to is that there is no name for the stack frame pointer you can use. There is no 'this' pointer that you can get at (even though it can be passed). Also note that lambdas are not necessarily delegates, they could be straight function pointers if they don't need a context: void main() { int a; pragma(msg, typeof((int b) => b * 2)); // int function(int b) pure nothrow @nogc @safe pragma(msg, typeof(() => a * 2)); // int delegate() pure nothrow @nogc @safe } Yes, but then this = null. I matters not for my use case. A question to ask is, why do you need it? Magic my friend! Magic!!!
Re: Allowing "fall through" of attributes
On Tuesday, 19 July 2016 at 16:09:38 UTC, Lodovico Giaretta wrote: On Tuesday, 19 July 2016 at 15:55:02 UTC, Rufus Smith wrote: I have some functions that take other functions. I would like the attributes to be able to "fall" through so I get overload like behavior. I only care that I am passing a function, not if it is shared, extern(C), pure, @nogc, etc. void foo(R, A...)(R function(A) bar) { alias type = typeof(bar); pragma(msg, type); // does magic with bar } foo never uses the attributes of bar explicitly. It uses type to instantiate other functions like bar. I have to create a foo for each attribute combination, which is not worth while. The code seems to break only for extern, the best I can tell, most attributes do pass through. But type does not contain these attributes. You shall do something like this (please note that I didn't check the docs while writing this; you shall definitely have a look at std.traits and consider the following as pseudo-code and not actual D): void foo(Fun)(Fun bar) if (isSomeFunction!Fun) // your constraint that bar is a function { // how to get your R and A types, if you need them: alias R = ReturnType!bar; alias A = Parameters!bar; alias type = Fun; pragma(msg, type); // do some magic } But this doesn't create a function with all the attributes of the original? Just one that has the same return type and parameters. What if Fun is pure or extern(C) or some other attributes? I'd like to create a function that is exactly the same in all regards as the original.
Allowing "fall through" of attributes
I have some functions that take other functions. I would like the attributes to be able to "fall" through so I get overload like behavior. I only care that I am passing a function, not if it is shared, extern(C), pure, @nogc, etc. void foo(R, A...)(R function(A) bar) { alias type = typeof(bar); pragma(msg, type); // does magic with bar } foo never uses the attributes of bar explicitly. It uses type to instantiate other functions like bar. I have to create a foo for each attribute combination, which is not worth while. The code seems to break only for extern, the best I can tell, most attributes do pass through. But type does not contain these attributes.
Re: How to get the "this" ptr of a lambda inside the lambda?
On Tuesday, 19 July 2016 at 06:46:44 UTC, Mike Parker wrote: On Tuesday, 19 July 2016 at 06:32:32 UTC, Rufus Smith wrote: Error: 'this' is only defined in non-static member functions, not __lambda2 Lambda's are delegates and delegates have a "this" type of pointer. I would like to get at it inside the lambda to check for some things. I'm doing some funky stuff. I'm not concerned about the scope or what this actually pointers to or anything like that, just need it's value for debugging. No, delegates do not have a "this" type of pointer. "this" is an implicit function parameter in a class or struct member function. Delegates have no such thing. The only generic way I know of to get at a delegate's function pointer inside the implementation is to explicitly add the pointer type to the parameter list as part of the declaration and pass it as an argument when you call the delegate. Delegates do have a this, they have a context pointer that is implicitly passed and used to access the outside context. It is no different than methods. Just because the explicit implementation details are different does not change the underlying meaning.
Get relative offset portably.
I am doing some weird stuff. I duplicate functions and modify them in a portable way. One problem I have is that I cannot get data in a relative way to be able to access attached functional data. Here is an kinda of thought example, void base(int a, int b, int c) { ... } This function is duplicated byte wise using memcpy. Extra information is added to the these bytes that I would like to access in base, but no absolute addresses can be used and portability must be maintained. One can imagine the data attached to the start or end of the function. Using assembly, it is relatively easy. Just get eip at start of function, get the length of the function, then access the data like mov eax, [eip+length]. This is not portable though. The function signature cannot change either or, it too, would be easy as I could just pass the offsets. I have no control over the calling mechanism. I can only create a functional template then copy that and attach data that it can use. I have seen some methods to do this but they all are unsafe as they might create undefined behavior in specific instances. Do I have any options? Thanks.
Re: Convert delegate or function type to other.
On Monday, 18 July 2016 at 20:15:30 UTC, John wrote: On Monday, 18 July 2016 at 18:49:22 UTC, Rufus Smith wrote: Suppose I have the following: alias func = void function(int); Is there a way to convert it automatically to something the same type except of delegate: alias del = toDel(func) = void delegate(int);? import std.traits; alias del = ReturnType!func delegate(Parameters!func); Thanks, I guess that allows me to change the parameters too!
How to get the "this" ptr of a lambda inside the lambda?
Error: 'this' is only defined in non-static member functions, not __lambda2 Lambda's are delegates and delegates have a "this" type of pointer. I would like to get at it inside the lambda to check for some things. I'm doing some funky stuff. I'm not concerned about the scope or what this actually pointers to or anything like that, just need it's value for debugging. Thanks.
Re: Convert delegate or function type to other.
On Monday, 18 July 2016 at 18:51:29 UTC, Jacob Carlborg wrote: On 2016-07-18 20:49, Rufus Smith wrote: Suppose I have the following: alias func = void function(int); Is there a way to convert it automatically to something the same type except of delegate: alias del = toDel(func) = void delegate(int);? https://dlang.org/phobos/std_functional.html#toDelegate No, that converts an actual function. I need to create a new alias from the old one. I'd also like to be able to create a delegate with a different context pointer.
Convert delegate or function type to other.
Suppose I have the following: alias func = void function(int); Is there a way to convert it automatically to something the same type except of delegate: alias del = toDel(func) = void delegate(int);?
Fast MSB to LSB
Is there any MSB to LSB and vice versa in phobos? Or some tricks with templates that make it fast as possible?