Re: Destructors can't be @nogc?

2021-07-24 Thread Jim via Digitalmars-d-learn

On Saturday, 24 July 2021 at 10:15:50 UTC, Mike Parker wrote:

Personally, I think `@nogc` on main is a bad idea. `@nogc` 
should be used as far down the call stack as you can put it. 
The higher it is, the more difficulty you're going to run into. 
I recommend you apply it only on functions that run in the 
hottest parts of a program. Those are the areas where GC 
allocations triggering collections can obviously become an 
issue. So start there.


Alright, I see where you're coming from, and I'm inclined to 
agree.
I'll look into constraining @nogc to performance-critical parts 
of the program.


But I think `destroy()` not being @nogc even though the 
destructor is tagged @nogc is a bug, and it should be fixed. 
Because it is problematic behaviour even if we limit the usage of 
@nogc.


Re: Destructors can't be @nogc?

2021-07-24 Thread Jim via Digitalmars-d-learn

On Saturday, 24 July 2021 at 02:02:00 UTC, Mike Parker wrote:
The problem is that you've marked main as `@nogc`, and 
`destroy` is not `@nogc`. Remove the annotation from main and 
it will compile.


In that case, what should we use to check functions called from 
`main` are not using the garbage collector?


Because it seems like we can't use classes with `@nogc`. We can 
write `.deinit()` for all our classes but what about the existing 
ones?





Destructors can't be @nogc?

2021-07-23 Thread Jim via Digitalmars-d-learn

Hello,

I've been playing with D and trying to understand how to work 
with @nogc. I must be doing something wrong, because even though 
I tagged the destructor for my class `@nogc`, I'm getting the 
following error: `.\min.d(27): Error: "@nogc" function "D main" 
cannot call non-@nogc function "object.destroy!(true, 
TestClass).destroy`


```D
import std.stdio : printf;
import core.lifetime : emplace;
import core.stdc.stdlib : malloc, free;

class TestClass {
int x;

this(int x) @nogc {
printf("TestClass's constructor called\n");
this.x = x;
}


~this() @nogc {
printf("TestClass's destructor called\n");
}
}

@nogc void
main() {
auto size = __traits(classInstanceSize, TestClass);
auto memory = malloc(size)[0..size];
TestClass x = emplace!(TestClass)(memory, 1);

printf("TestClass.x = %d\n", x.x);

destroy(x);
free(cast(void*)x);
}

```

What is the problem here? Should I not call `destroy`? If so, 
what should I call instead?





Re: How to "Clear the Screen" for Windows Command Processor? (Windows 10)

2019-05-21 Thread Jim via Digitalmars-d-learn

On Tuesday, 21 May 2019 at 07:16:29 UTC, Boqsc wrote:
I'm getting unsure why executeShell works on the pause command, 
but cls that is responsible for clearing the text do not.


import std.stdio, std.process;
void main()
{
writeln("Some text that will appear in cmd");
executeShell("cls"); // Does not clear the text?
	executeShell("pause"); // Pauses the cmd.exe to keep from 
closing itself.

}


As far as I understand [1], executeShell starts a new shell and 
executes %command% in that shell. So cls wouldn't be called in 
the shell where you wrote Some text...


[1] https://dlang.org/phobos/std_process.html#.executeShell


Re: Casting to interface not allowed in @safe code?

2019-05-21 Thread Jim via Digitalmars-d-learn

On Tuesday, 21 May 2019 at 07:33:17 UTC, rumbu wrote:

On Tuesday, 21 May 2019 at 07:16:49 UTC, Jim wrote:

On Tuesday, 21 May 2019 at 07:04:27 UTC, rumbu wrote:

On Tuesday, 21 May 2019 at 05:51:30 UTC, Jim wrote:

That's because foo is of type Base, not implementing FeatureX.


Right, Base isn't implementing FeatureX, but foo is really a 
Foo


That's your knowledge, for the compiler foo is really a Base, 
as written in your own code.




Yes, thinking about it again it makes sense.


Re: Casting to interface not allowed in @safe code?

2019-05-21 Thread Jim via Digitalmars-d-learn

On Tuesday, 21 May 2019 at 07:19:38 UTC, Marco de Wild wrote:

On Tuesday, 21 May 2019 at 05:51:30 UTC, Jim wrote:

Hi,

consider this:

interface Base
{
  void setup();
}

interface FeatureX
{
  void x();
}

class Foo: Base, FeatureX
{
  void setup(){};
  void x(){};
}

void main()
{
  Base foo = new Foo(); // This would be the result of a 
factory class


  (cast(FeatureX)foo).x(); // 1
}

1) error: casting to interface FeatureX is not allowed in 
@safe code.


Question: How to call foo.x in @safe code ?


I got it compiling using `(cast(FeatureX)(cast(Foo)foo)).x();`, 
but I don't really recommend it. As far as the compiler is 
concerned, `Base` and `FeatureX` are not related in any way 
(I'd still expect it to work though). I don't know the 
circumstances of your problem (so some assumptions here), but 
usually casting is not the best option. You are basically 
overriding the type system manually. Some suggestions you can 
evaluate:

- Extend the base interface:
interface FeatureX : Base { /+...+/}
or
interface Combined : FeatureX, Base {}

- Change the factory class to return either Foo, FeatureX or a 
templated type (if it's a more general factory class). This way 
we can leverage the type system.


- You can also make the cast @trusted, but that seems like it 
kinda defeats the purpose of the function being @safe...




The problem I'm trying to solve is I've got to implement a few 
Backends and some features are present in one Backend and not in 
another, depending on the OS or the underlying library.


So the idea was to implement the Base interface for each Backend 
and then additionally the extra features but not those that 
wouldn't make sense or aren't present in the library.


In the Backend implementation I know that I'm always dealing with 
an object that implements the Base interface and all the Feature 
interfaces.


The point of the Base interface is to be able to store those 
objects into an array.


I could just put all those Features into the Base interface but 
then for a few Backends I would end up with a lot of functions 
that would return nothing or throw an exception.


The combined interfaces looks good. Thanks.


---
Returning to the original point (the cast is disallowed in safe 
code), I don't think it is listed in the spec: 
https://dlang.org/spec/function.html#safe-functions Unless I am 
missing some implementation details about interfaces, I would 
expect it to work just like class casts (i.e. return null on a 
failed cast, thereby having defined behaviour, thereby being 
@safe).


That was my expectation as well. But since the 2 interfaces 
aren't related it kind of makes sense.


Re: Casting to interface not allowed in @safe code?

2019-05-21 Thread Jim via Digitalmars-d-learn

On Tuesday, 21 May 2019 at 07:04:27 UTC, rumbu wrote:

On Tuesday, 21 May 2019 at 05:51:30 UTC, Jim wrote:

That's because foo is of type Base, not implementing FeatureX.


Right, Base isn't implementing FeatureX, but foo is really a Foo 
which does:



class Foo: Base, FeatureX
{
  void setup(){};
  void x(){};
}


and it works in @system code.


Question on syntax

2016-11-08 Thread Jim via Digitalmars-d-learn

Hi,

I'm a very experienced C++ programmer, looking at a program 
written in D. D is similar enough to C++ and Java that I have no 
problem understanding it - except for one thing. I think I may 
have figured it out, but I want to confirm my understanding.


What does it mean when a variable name starts with a '.'

Here's an extract from the code:
/// move.d 
module move;

import empire;
import eplayer;
import sub2;

[...]

void updlst(loc_t loc,int type) // update map value at loc
{
   int ty = .typ[.map[loc]];// what's there

... etc.
(loc_t is an alias for int)

Would the equivalent in C or C++ be:

typedef int loc_t;
extern int typ[];
extern int map[];
void updlst( loc_t loc, int type )
{
   int ty = typ[map[loc]];

/// var.d  
module var;
import empire;
import eplayer;

int typ[MAPMAX] = ...etc...
ubyte map[MAPSIZE] = [0,];  // reference map

If you need more context, the complete source code is available 
from http://www.classicempire.com/