Re: Struct initialization extra comma - should it compile

2021-04-25 Thread Bastiaan Veelo via Digitalmars-d-learn

On Sunday, 25 April 2021 at 13:39:54 UTC, JN wrote:

struct Foo
{
int x, y, z;
}

void main()
{
 Foo bar = Foo(1,);
}

This compiles without syntax errors, is this expected?


Yes, the 
[specification](https://dlang.org/spec/declaration.html#StructInitializer) is like this:

```
StructMemberInitializers:
StructMemberInitializer
StructMemberInitializer ,
StructMemberInitializer , StructMemberInitializers
```

— Bastiaan.


Re: Struct initialization extra comma - should it compile

2021-04-25 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 25 April 2021 at 13:39:54 UTC, JN wrote:

struct Foo
{
int x, y, z;
}

void main()
{
 Foo bar = Foo(1,);
}

This compiles without syntax errors, is this expected?


Yes, D allows trailing commas in argument lists.


Struct initialization extra comma - should it compile

2021-04-25 Thread JN via Digitalmars-d-learn

struct Foo
{
int x, y, z;
}

void main()
{
 Foo bar = Foo(1,);
}

This compiles without syntax errors, is this expected?


Re: Should it compile?

2020-06-07 Thread Stanislav Blinov via Digitalmars-d-learn

On Sunday, 7 June 2020 at 23:09:41 UTC, Jack Applegame wrote:

auto const_ua = Unique!(const NonCopyable)(move(ca)); // 
error, why???

}
```


Moving *from* a const would violate const. At least, until such 
time that the compiler is finally taught about move() (hopefully, 
sometime this decade).


`move` and `moveEmplace` take arguments by ref. Therefore, if you 
call them with a const lvalue, arguments will be ref const. Which 
are allowed to bind to both mutable, const *and*  immutable, and 
implementations of `move` and `moveEmplace` are not able to 
assume either way. Const is const.


`emplace` violates const (it has to). Perhaps `moveEmplace` 
should also be allowed to violate const for its *second* 
argument, but not the first, on the assumption that the 
programmer knows what they're doing.


Problem here is that, well, it wouldn't be as straightforward as 
it sounds, because the language allows overloading constructors 
based on `const` and `immutable`. So you may end up moving into a 
const such state that that const is not equipped to deal with:


struct S {
private { int i; bool iAmConst; }
this(int i) { this.i = i; }
this(int i) const { this.i = i; iAmConst = true; }
}

S mutableS = 42;
const S constS = void;
moveEmplace(mutableS, constS); // if this was allowed, now what?
assert(constS.iAmConst);   // <- this would fail

An attempt was made to solve this (albeit the intended use case 
was different - impure moves), via DIP1014 and opPostMove. The 
DIP was even accepted. But apparently, it failed, for the above 
reason.


Here's hoping that move constructors do make it into the 
language, so that these darker places of the standard library (or 
rather, runtime nowadays) may die in peace.


Re: Should it compile?

2020-06-07 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 7 June 2020 at 23:09:41 UTC, Jack Applegame wrote:

const NonCopyable const_a;
auto const_ua = Unique!(const NonCopyable)(move(ca)); // 
error, why???


You can't move from a const variable.


Re: Should it compile?

2020-06-07 Thread Jack Applegame via Digitalmars-d-learn

On Saturday, 6 June 2020 at 11:58:06 UTC, Basile B. wrote:

maybe it shouldn't but then with another message, for example

Error, cannot `void` initialize a `const` declaration.

since that makes very little sense, at least as a local 
variable. (as a member, this can be initialized in a 
constructor)

The local variable is just an example.
I need to move a constant structure from one place in memory to 
another.


I want to write something like C++ std::unique_ptr.

Consider (this is not real code, but just a simple example):
https://run.dlang.io/is/mUUU8c
```
import core.memory : pureMalloc, pureFree;
import std.algorithm : move, moveEmplace;
import std.traits : hasElaborateDestructor;

struct NonCopyable {
this(this) @disable;
}

struct Unique(T) {
this(this) @disable;
T* m_data;
this(T data) {
m_data = cast(T*) pureMalloc(T.sizeof);
moveEmplace(data, *m_data);
}
~this() {
if(m_data) {
	static if(hasElaborateDestructor!T) (cast(Unqual!T*) 
m_data).__xdtor;

pureFree(m_data);
}
}
}

void main() {
NonCopyable a;
auto ua = Unique!NonCopyable(move(a)); // fine

const NonCopyable const_a;
auto const_ua = Unique!(const NonCopyable)(move(ca)); // 
error, why???

}
```



Re: Should it compile?

2020-06-07 Thread Jack Applegame via Digitalmars-d-learn

On Saturday, 6 June 2020 at 12:02:03 UTC, MoonlightSentinel wrote:

On Saturday, 6 June 2020 at 08:55:20 UTC, Jack Applegame wrote:

Should it compile?


No, moveEmplace just sees a const reference and doesn't know 
that a is void-initialized.
Actually, it knows. Because moveEmplace assumes target is 
uninitialized.


Re: Should it compile?

2020-06-06 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 6 June 2020 at 12:54:38 UTC, Stanislav Blinov wrote:


The moveEmpalce should compile...


But not when the *first* argument is const though, like in the 
example. For *that*, one would have to insert an additional cast.


Re: Should it compile?

2020-06-06 Thread Stanislav Blinov via Digitalmars-d-learn

On Saturday, 6 June 2020 at 11:58:06 UTC, Basile B. wrote:

On Saturday, 6 June 2020 at 08:55:20 UTC, Jack Applegame wrote:

Should it compile?
I think, it should.


maybe it shouldn't but then with another message, for example

Error, cannot `void` initialize a `const` declaration.

since that makes very little sense, at least as a local 
variable. (as a member, this can be initialized in a 
constructor)


The moveEmpalce should compile, just like this does:

import std.conv : emplace;

emplace(&a, 'a');

But, in the case of emplacing into a const, either should be 
@system (moveEmplace is always @system, but `emplace` for this 
case is not at the moment).


One could do a

emplace(&a, move(b))

but that's more moves (and I believe current emplace even would 
insert a spurious copy there).


This is what we get for delegating emplacement and moves into a 
library instead of having appropriate intrinsics.


Re: Should it compile?

2020-06-06 Thread MoonlightSentinel via Digitalmars-d-learn

On Saturday, 6 June 2020 at 08:55:20 UTC, Jack Applegame wrote:

Should it compile?


No, moveEmplace just sees a const reference and doesn't know that 
a is void-initialized.


Re: Should it compile?

2020-06-06 Thread Basile B. via Digitalmars-d-learn

On Saturday, 6 June 2020 at 08:55:20 UTC, Jack Applegame wrote:

Should it compile?

```d
import std.algorithm.mutation;

void main() {
const char a = void;
const char b ='b';
moveEmplace(b, a); // mutation.d: Error: cannot modify 
const expression target

assert(a == 'b');
}
```
I think, it should.


maybe it shouldn't but then with another message, for example

Error, cannot `void` initialize a `const` declaration.

since that makes very little sense, at least as a local variable. 
(as a member, this can be initialized in a constructor)




Should it compile?

2020-06-06 Thread Jack Applegame via Digitalmars-d-learn

Should it compile?

```d
import std.algorithm.mutation;

void main() {
const char a = void;
const char b ='b';
moveEmplace(b, a); // mutation.d: Error: cannot modify const 
expression target

assert(a == 'b');
}
```
I think, it should.