Re: Is there a way to do the same thing in entry and return of a bunch of functions?
On Wednesday, 18 September 2019 at 01:03:27 UTC, Nicholas Wilson wrote: I think a mixin that does string LOG_SCOPE = q{ callDepth++; scope(exit) callDepth--; } is probably the easiest. for bonus points string LOG_SCOPE = q{ callDepth++; debug_log(__FUNCTION__);// or __PRETTY_FUNTION__ scope(exit) callDepth--; } and the mixin(LOG_SCOPE); Yes that's what I meant sort of the mixin (where we can also put local scope inside etc.). I mean you _could_ do some UDA reflection to generate wrapping function that do the indentation, bit that is overkill. Interesting, I didn't know about that. I didn't completely get it but I get that it seems the easier way to do it is the mixin. Thanks, Stefanos
Is there a way to do the same thing in entry and return of a bunch of functions?
I think it's better to give a concrete example rather than explaining this vaguely. - For those who are familiar with LDC internals: I want to create something like LOG_SCOPE. You can skip the explanation. - For those who are not: Imagine that you want to track down how deep in the call stack you are, so that you can print nice log messages. That is, if you have: func3() { debug_log("message in func3"); } func2() { debug_log("message in func2"); func3(); debug_log("message in func2"); } func1() { func2(); } main() { func1(); } In this case, I'd like to have something like this: * * message in func 2 * * * message in func3 * * message in func2 So, we could create a global variable CALL_DEPTH or smth, and in every function right at the beginning, do: CALL_DEPTH += 1; and in the end: CALL_DEPTH -= 1; And then implement debug_log as (skipping the printf-like things etc.): for (int i = 0; i != CALL_DEPTH; ++i) printf("* "); But the thing is, now we have to put the += and -= in every function, when it is really common in all of them and there's no reason to be visible anyway. LDC does something that IMO is ingenious. It's something like (it's C++): #define LOG_SCOPE LoggerObj _logscope; But LoggerObj has a constructor that does the += and the destructor that does -=. So, you can put just one line of: LOG_SCOPE; at any point inside a function and the desired thing is done almost invisibly. -- The question -- Can we do better ? For one, I believe that because D does not have a preprocessor, we have to do an actual declaration which would be somewhat more verbose. Or do a mixin that does it. mixin can help as it can be more complicated and also we can access local scope (although I don't think this is a good idea). But in both cases, they're not totally invisible. Can we do something like: func1, func2 and func3, when they enter do the X and when they return, they do the Y. Thanks, Stefanos
Re: Undefined reference - built from source DMD
On Wednesday, 11 September 2019 at 02:09:42 UTC, Stefanos Baziotis wrote: I have branched to an old PR (4 months ago) and the problem doesn't exist. For clarification, the problem doesn't exist _in that_ branch. On my current new branch, I still haven't been able to solve it.
Re: Undefined reference - built from source DMD
On Tuesday, 10 September 2019 at 15:01:11 UTC, Stefanos Baziotis wrote: On Tuesday, 10 September 2019 at 14:47:00 UTC, Nicholas Wilson wrote: Is this you have built your own DMD Yes I have branched to an old PR (4 months ago) and the problem doesn't exist.
Re: Undefined reference - built from source DMD
On Tuesday, 10 September 2019 at 14:47:00 UTC, Nicholas Wilson wrote: Is this you have built your own DMD Yes and using it to compile a test program and you get that error, or you get that error trying to build DMD? Both. I get that error trying to compile _any_ program.
Undefined reference - built from source DMD
I don't if this the right group to post this. DMD built from source fails to link / find `main`. The error is: /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o: In function `_start': (.text+0x20): undefined reference to `main' collect2: error: ld returned 1 exit status Error: linker exited with status 1 Does anyone know how this could have happened?
Re: Is there a way to slice non-array type in @safe?
Thank you all for your responses. I understand that the compiler can't ensure @safe and @trusted is needed.. I'm not familiar though with all aspects of D and thought I might have missed something. On Friday, 12 July 2019 at 01:24:06 UTC, Jonathan M Davis wrote: BTW, if you're implementing memcmp, why are you using byte instead of ubyte? byte is signed. Unless you're explicitly trying to do arithmetic on integral values from -127 to 127, odds are, you shouldn't be using byte. If you're doing something like breaking an integer into its 8-bit parts, then ubyte is what's appropriate, not byte. I usually start with the signed version and if in the end there's no need for the signed, I make it unsigned. In this case, at the moment there's no actual need for `byte`. Actually, it only makes difficult to use some GDC intrinsics.
Re: Is there a way to slice non-array type in @safe?
On Thursday, 11 July 2019 at 19:37:38 UTC, Nathan S. wrote: If you know that what you're doing cannot result in memory corruption but the compiler cannot automatically infer @safe, it is appropriate to use @trusted. (For this case make sure you're not returning the byte slices, since if the arguments were allocated on the stack you could end up with a pointer to an invalid stack frame. If it's the caller's responsibility to ensure the slice doesn't outlive the struct then it is the caller that should be @trusted or not.) Yes, @trusted is an option. I mean it's a good solution, but from the standpoint of the language user, it seems unfortunate that for the case static types @trusted has to be used while the array one can be @safe: int memcmp(T)(const T[] s1, const T[] s2) @safe { const byte[] s1b = (cast(const(byte[]))s1)[0 .. s1.length * T.sizeof]; const byte[] s2b = (cast(const(byte[]))s2)[0 .. s2.length * T.sizeof]; }
Re: Is there a way to slice non-array type in @safe?
On Thursday, 11 July 2019 at 18:46:57 UTC, Paul Backus wrote: What's the actual problem you're trying to solve? There may be a different way to do it that's @safe. I hope I answered the "what". In case the "why" helps too, it is because I'm implementing memcmp().
Re: Is there a way to slice non-array type in @safe?
On Thursday, 11 July 2019 at 18:46:57 UTC, Paul Backus wrote: Casting from one type of pointer to another and slicing a pointer are both @system, by design. Yes, I'm aware, there are no pointers in the code. The pointer was used here because it was the only way to solve the problem (but not in @safe). What's the actual problem you're trying to solve? There may be a different way to do it that's @safe. I want to make an array of bytes that has the bytes of the value passed. For example, if T = int, then I want an array of 4 bytes that has the 4 individual bytes of `s1` let's say. For long, an array of 8 bytes etc. Ideally, that would work with `ref` (i.e. the bytes of where the ref points to).
Is there a way to slice non-array type in @safe?
I searched the forum but did not find something. I want to do this: int foo(T)(ref T s1, ref T s2) { const byte[] s1b = (cast(const(byte)*)&s1)[0 .. T.sizeof]; const byte[] s2b = (cast(const(byte)*)&s2)[0 .. T.sizeof]; } Which is to create a byte array from the bytes of the value given, no matter the type. The above works, but it's not @safe. Thanks, Stefanos
Re: Is there a way to load a `RIP` register relative address in inline asm?
On Tuesday, 18 June 2019 at 17:10:50 UTC, Adam D. Ruppe wrote: On Tuesday, 18 June 2019 at 17:09:48 UTC, Adam D. Ruppe wrote: pop EAX; errr you can see my 32 bit bias here (forgive me, I'm old), but you know what i mean :) Thank you, quite clever. There is also the "$" symbol that is related: https://dlang.org/spec/iasm.html#special_symbols
Is there a way to load a `RIP` register relative address in inline asm?
I can't do for example: lea RAX, [RIP+something]; Generally, RIP does not seem to be available.
Re: Passing a pointer to a function (by value) changes the pointer value
On Sunday, 28 April 2019 at 18:48:55 UTC, Adam D. Ruppe wrote: Sounds like you have a stack corruption bug somewhere else... memory being overwritten by something else. Can you post any more of the context code? I fixed it, there was a bug, but not related to stack. Not related to memory at all. As I was trying to fix the bug, the code changed unfortunately and now I try to reproduce the bug but I can't. I use visual D and one interesting point is that one file of the project was not added, but the compiler didn't yield an error although it tried to use its functions (but actually couldn't, I don't know how that can happen too. Using dmd from terminal, that never happens). I think that by adding the file, the changing of pointer value disappeared, but it could also be that in the process, I fixed a memory bug that I didn't notice (although that is quite unlikely). If I can reproduce it, I'll post it. Thanks anyway, - Stefanos
Passing a pointer to a function (by value) changes the pointer value
Hello everyone, I have a function: void foo(T *t) { ... } void bar(...) { T *t = ...; foo(t); } In the debugger, before calling 'foo', 't' had a value (an address) let's say 10. Stepping into 'foo', the 't' that 'foo' got, which is supposed to have the same value that the 't' in 'bar' had, actually had a completely different value. That caused a very bad bug... I thought that D behaves in that kind of situations as C/C++, and so I thought 'foo' should get the same value but that was not true. Needless to say it took a lot of time to notice it as I would never expect it and I still don't know how to fix it. How does this happen? Is there are some specifics about pointers and / or passing arguments that I should know? What is also puzzling is that the project is about 4500 lines of D code _full_ of pointers and this happens in all calls I have checked and _somehow_ it was working up until now. Best regards, Stefanos Baziotis
Re: Convert array to custom type when passing function argument
On Wednesday, 17 April 2019 at 23:44:42 UTC, Adam D. Ruppe wrote: In C++, if you define a struct/class, and constructors apply for this. struct Test { Test(const char* foo) {} }; void cool(Test t) {} cool("string"); // works That works in C++, unless you mark that constructor with `explicit` struct Test { explicit Test(const char* foo) {} // this opts out of the cool thing above }; Yes, thanks. :) Actually, I asked initially because in C++ you can do the thing I described. I thought that you meant something I missed with out-out. - Stefanos
Re: Convert array to custom type when passing function argument
On Wednesday, 17 April 2019 at 16:33:17 UTC, Adam D. Ruppe wrote: [...] Thanks for the info! I argue C++'s mistake was *out-out* implicit construction What do you mean by out-out? - Stefanos
Re: Convert array to custom type when passing function argument
On Wednesday, 17 April 2019 at 12:48:52 UTC, Adam D. Ruppe wrote: This is the "implicit construction" I sometimes talk about and D doesn't support it, by design (alas). Sorry if this has been asked again, I didn't find anything. Do we know the reason why it is not supported? There's two options you can do: 1) offer an overload to your function that does the conversion: void test(Buf!int arr) { /* impl here */ } void test(int[] arr) { test(Buf!int(arr)); } // just forward to the other or 2) Offer a helper construction function you can call, like: Buf!int toBuf(int[] a) { return Buf!int(a); } and then you can call the function like test([1, 2, 3].toBuf); // calling your function at the end Yes, I had done the 2), which means for 50 functions, I have another 50 functions. Because of the constructor these are one-liners but still, it's kind of ugly. I didn't know about the 3) thanks! I think it's not a very good solution for this kind of problems but cool otherwise. - Stefanos
Convert array to custom type when passing function argument
I have a custom Buf struct (working as a simple vector) struct Buf(T) { size_t cap, len; T *data; @nogc this(T[] arr) { reserve(arr.length); foreach(item; arr) { push(item); } } ... }; And I have a function like this: void test(Buf!(int) buf) { } I want to be able to make it work array-like to have compact function calls. Something like this: test([1,2,3]); Currently I have the constructor shown and with that I do: test(Buf!(int)([1,2,3]); which is compact but can it be done differently? Meaning, if a function takes a Buf!(T), can it also take a T[] and construct a Buf!(T) using some constructor? Thanks in advance!