Comment #0 by bearophile_hugs — 2012-07-10T15:18:42Z
I am not sure, but I think this code is correct:
struct Foo {
int[2] bar;
}
const(int[2]) spam() {
const Foo* x;
return true ? x.bar : [10, 20];
}
void main() {}
But DMD 2.060alpha gives:
test.d(6): Error: cannot implicitly convert expression (cast(const(int)[])(*x).bar) of type const(int)[] to const(int[2u])
Comment #1 by bugzilla — 2012-07-10T16:36:56Z
The type of
[1,2]
is int[], not int[2].
Comment #2 by timon.gehr — 2012-07-10T16:56:28Z
The [1,2] / [10,20] literal implicitly converts to int[2].
It is similar to the following:
struct Foo{
short bar;
}
short spam() {
const Foo* x;
return true ? x.bar : 1;
}
Comment #3 by bearophile_hugs — 2012-07-10T17:49:56Z
(In reply to comment #1)
> The type of
>
> [1,2]
>
> is int[], not int[2].
Usually in my bug reports I add some cases where the code works, to avoid troubles like this one.
This works:
struct Foo {
int[2] bar;
}
int[2] spam() {
Foo* x;
return true ? x.bar : [10, 20];
}
void main() {}
This too works:
struct Foo {
int[2] bar;
}
const(int[2]) spam() {
const Foo* x;
const(int[2]) r = true ? x.bar : [10, 20];
return r;
}
void main() {}
Comment #4 by yebblies — 2013-01-16T07:22:44Z
Is this the same as issue 8277?
Comment #5 by yebblies — 2013-11-25T07:30:24Z
The problem is, while [10,20] converts to int[2], int[2] converts to int[]. int[] is picked as the common type. I'm not entirely sure we want to change that.
Comment #6 by bearophile_hugs — 2013-11-25T07:42:13Z
(In reply to comment #5)
> The problem is, while [10,20] converts to int[2], int[2] converts to int[].
> int[] is picked as the common type. I'm not entirely sure we want to change
> that.
I think ?: is supposed to pick the most specialized type of the two. And I think int[2] contains more information than int[], so it's more specialized.
Comment #7 by bearophile_hugs — 2013-11-26T05:08:07Z
(In reply to comment #5)
> The problem is, while [10,20] converts to int[2], int[2] converts to int[].
> int[] is picked as the common type. I'm not entirely sure we want to change
> that.
The current situation is a little more subtle:
int[2] foo1() {
int[2] a;
return true ? a : [1, 2]; // OK
}
const(int[2]) foo2() {
int[2] a;
return true ? a : [1, 2]; // OK
}
const(int[2]) foo3() {
const int[2] a;
return true ? a : [1, 2]; // error
}
void main() {}
Comment #8 by yebblies — 2013-11-26T05:13:24Z
(In reply to comment #7)
>
> The current situation is a little more subtle:
>
> int[2] foo1() {
> int[2] a;
> return true ? a : [1, 2]; // OK
> }
> const(int[2]) foo2() {
> int[2] a;
> return true ? a : [1, 2]; // OK
> }
> const(int[2]) foo3() {
> const int[2] a;
> return true ? a : [1, 2]; // error
> }
> void main() {}
Ah, that bug. I saw one recently with enum:
enum E { a }
bool b;
void main()
{
E x = E.a;
const E y = E.a;
pragma(msg, typeof(b ? x : y)); // prints int
}
Comment #9 by robert.schadek — 2024-12-13T18:00:39Z