Re: prolog and epilog code

2016-08-02 Thread Rufus Smith via Digitalmars-d-learn

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

2016-08-02 Thread Rufus Smith via Digitalmars-d-learn
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

2016-08-02 Thread Rufus Smith via Digitalmars-d-learn
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

2016-08-02 Thread Rufus Smith via Digitalmars-d-learn

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

2016-08-02 Thread Rufus Smith via Digitalmars-d-learn
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

2016-08-01 Thread Rufus Smith via Digitalmars-d-learn
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

2016-07-31 Thread Rufus Smith via Digitalmars-d-learn
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

2016-07-31 Thread Rufus Smith via Digitalmars-d-learn

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

2016-07-23 Thread Rufus Smith via Digitalmars-d-learn
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

2016-07-23 Thread Rufus Smith via Digitalmars-d-learn

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

2016-07-23 Thread Rufus Smith via Digitalmars-d-learn
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

2016-07-23 Thread Rufus Smith via Digitalmars-d-learn
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

2016-07-23 Thread Rufus Smith via Digitalmars-d-learn

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

2016-07-23 Thread Rufus Smith via Digitalmars-d-learn
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

2016-07-23 Thread Rufus Smith via Digitalmars-d-learn
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

2016-07-22 Thread Rufus Smith via Digitalmars-d-learn

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

2016-07-22 Thread Rufus Smith via Digitalmars-d-learn
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

2016-07-21 Thread Rufus Smith via Digitalmars-d-learn

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

2016-07-21 Thread Rufus Smith via Digitalmars-d-learn

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

2016-07-19 Thread Rufus Smith via Digitalmars-d-learn
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

2016-07-19 Thread Rufus Smith via Digitalmars-d-learn

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

2016-07-19 Thread Rufus Smith via Digitalmars-d-learn
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

2016-07-19 Thread Rufus Smith via Digitalmars-d-learn
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

2016-07-19 Thread Rufus Smith via Digitalmars-d-learn

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

2016-07-19 Thread Rufus Smith via Digitalmars-d-learn

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?

2016-07-19 Thread Rufus Smith via Digitalmars-d-learn
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?

2016-07-19 Thread Rufus Smith via Digitalmars-d-learn
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

2016-07-19 Thread Rufus Smith via Digitalmars-d-learn

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

2016-07-19 Thread Rufus Smith via Digitalmars-d-learn
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?

2016-07-19 Thread Rufus Smith via Digitalmars-d-learn

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.

2016-07-19 Thread Rufus Smith via Digitalmars-d-learn
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.

2016-07-19 Thread Rufus Smith via Digitalmars-d-learn

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?

2016-07-19 Thread Rufus Smith via Digitalmars-d-learn
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.

2016-07-18 Thread Rufus Smith via Digitalmars-d-learn

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.

2016-07-18 Thread Rufus Smith via Digitalmars-d-learn

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

2016-07-17 Thread Rufus Smith via Digitalmars-d-learn
Is there any MSB to LSB and vice versa in phobos? Or some tricks 
with templates that make it fast as possible?