| Thread overview |
|---|
February 21, 2014 immutable int n = Test(); int[n] x;---- compiles, but __ctfe is false. How? | ||||
|---|---|---|---|---|
| ||||
Attempting to learn CTFE, I tried the following test.
size_t counter;
uint Test()
{
if (!__ctfe)
{
++counter;// This code is for execution at run time
}
return 2;
}
void main()
{
writeln("counter = ", counter);
immutable int n = Test();
int[n] arr;
writeln("arrary length = ", arr.length, " ; counter = ", counter);
}
output:
counter = 0
arrary length = 2 ; counter = 1
For array declaration to be successful, its size has to be known at compile time. The above code compiles too. But __ctfe seems to be false while performing Test().
Instead, if I write
int[Test()] c;
writeln("c.length = ", c.length, " ; counter = ", counter);
output is
counter = 0
c.length = 2 ; counter = 0
What is wrong in my mind?
Thanks,
Gopan
| ||||
February 21, 2014 Re: immutable int n = Test(); int[n] x;---- compiles, but __ctfe is false. How? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Gopan | On Friday, 21 February 2014 at 13:38:58 UTC, Gopan wrote:
> Attempting to learn CTFE, I tried the following test.
>
> size_t counter;
>
> uint Test()
> {
> if (!__ctfe)
> {
> ++counter;// This code is for execution at run time
> }
> return 2;
> }
>
> void main()
> {
> writeln("counter = ", counter);
>
> immutable int n = Test();
> int[n] arr;
> writeln("arrary length = ", arr.length, " ; counter = ", counter);
> }
>
> output:
> counter = 0
> arrary length = 2 ; counter = 1
>
> For array declaration to be successful, its size has to be known at compile time. The above code compiles too. But __ctfe seems to be false while performing Test().
>
> Instead, if I write
> int[Test()] c;
> writeln("c.length = ", c.length, " ; counter = ", counter);
> output is
> counter = 0
> c.length = 2 ; counter = 0
>
> What is wrong in my mind?
>
> Thanks,
> Gopan
Use enum n = Test() or make immutable n global variable i.e. place it before main.
| |||
February 21, 2014 Re: immutable int n = Test(); int[n] x;---- compiles, but __ctfe is false. How? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to FreeSlave | Another strange thing:
import std.stdio;
uint Test()
{
if (!__ctfe)
{
return 3;
}
return 2;
}
void main()
{
immutable n = Test();
int[n] arr;
writeln("arrary length = ", arr.length, " ; n = ", n);
}
Output:
arrary length = 2 ; n = 3
When you think about it you understand that it's logically right behavior, but it's not acceptable in practice.
| |||
February 21, 2014 Re: immutable int n = Test(); int[n] x;---- compiles, but __ctfe is false. How? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Gopan | On Friday, 21 February 2014 at 13:38:58 UTC, Gopan wrote: > Attempting to learn CTFE, I tried the following test. > > size_t counter; > > uint Test() > { > if (!__ctfe) > { > ++counter;// This code is for execution at run time > } > return 2; > } > > void main() > { > writeln("counter = ", counter); > > immutable int n = Test(); As this is a local variable, this is a runtime initialization, no __ctfe here. Doesn't matter that it's immutable. It's static/global vs local. So, this correctly does ++counter. Make it static immutable n, and counter won't be incremented. > int[n] arr; Not sure if this should compile. n is a run-time value. It just happens that it can be CTFE'd. A more problematic case: --- void main() { immutable n = __ctfe ? 1 : 2; int[n] a; assert(a.length == n); // fails, wat } --- > writeln("arrary length = ", arr.length, " ; counter = ", counter); > } > > output: > counter = 0 > arrary length = 2 ; counter = 1 > > For array declaration to be successful, its size has to be known at compile time. The above code compiles too. But __ctfe seems to be false while performing Test(). > > Instead, if I write > int[Test()] c; > writeln("c.length = ", c.length, " ; counter = ", counter); > output is > counter = 0 > c.length = 2 ; counter = 0 > > What is wrong in my mind? > > Thanks, > Gopan | |||
February 21, 2014 Re: immutable int n = Test(); int[n] x;---- compiles, but __ctfe is false. How? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to FreeSlave | On Friday, 21 February 2014 at 14:04:45 UTC, FreeSlave wrote:
> Another strange thing:
>
> import std.stdio;
>
> uint Test()
> {
> if (!__ctfe)
> {
> return 3;
> }
> return 2;
> }
>
>
>
> void main()
> {
> immutable n = Test();
> int[n] arr;
> writeln("arrary length = ", arr.length, " ; n = ", n);
> }
>
> Output:
> arrary length = 2 ; n = 3
>
> When you think about it you understand that it's logically right behavior, but it's not acceptable in practice.
It looks like 'immutable n = Test();' is executed during both compile time and runtime. Is that what is happening?
| |||
February 21, 2014 Re: immutable int n = Test(); int[n] x;---- compiles, but __ctfe is false. How? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Gopan | On 02/21/2014 08:46 AM, Gopan wrote:
> On Friday, 21 February 2014 at 14:04:45 UTC, FreeSlave wrote:
>> Another strange thing:
>>
>> import std.stdio;
>>
>> uint Test()
>> {
>> if (!__ctfe)
>> {
>> return 3;
>> }
>> return 2;
>> }
>>
>>
>>
>> void main()
>> {
>> immutable n = Test();
>> int[n] arr;
>> writeln("arrary length = ", arr.length, " ; n = ", n);
>> }
>>
>> Output:
>> arrary length = 2 ; n = 3
>>
>> When you think about it you understand that it's logically right
>> behavior, but it's not acceptable in practice.
>
> It looks like 'immutable n = Test();' is executed during both compile
> time and runtime. Is that what is happening?
Yes. The compiler needs the value of n at compile time so it evaluates it at compile time.
I agree that it is confusing but I feel like it is the responsibility of the programmer to ensure consistent behavior.
Ali
| |||
February 23, 2014 Re: immutable int n = Test(); int[n] x;---- compiles, but __ctfe is false. How? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Friday, 21 February 2014 at 17:04:45 UTC, Ali Çehreli wrote: > On 02/21/2014 08:46 AM, Gopan wrote: > > > On Friday, 21 February 2014 at 14:04:45 UTC, FreeSlave wrote: > >> Another strange thing: > >> > >> import std.stdio; > >> > >> uint Test() > >> { > >> if (!__ctfe) > >> { > >> return 3; > >> } > >> return 2; > >> } > >> > >> > >> > >> void main() > >> { > >> immutable n = Test(); > >> int[n] arr; > >> writeln("arrary length = ", arr.length, " ; n = ", n); > >> } > >> > >> Output: > >> arrary length = 2 ; n = 3 > >> > >> When you think about it you understand that it's logically > right > >> behavior, but it's not acceptable in practice. > > > > It looks like 'immutable n = Test();' is executed during both > compile > > time and runtime. Is that what is happening? > > Yes. The compiler needs the value of n at compile time so it evaluates it at compile time. Thanks for confirming this, Ali. > I agree that it is confusing but I feel like it is the responsibility of the programmer to ensure consistent behavior. > > Ali | |||
February 23, 2014 Re: immutable int n = Test(); int[n] x;---- compiles, but __ctfe is false. How? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to anonymous | On Friday, 21 February 2014 at 14:14:14 UTC, anonymous wrote:
> Not sure if this should compile. n is a run-time value. It just
> happens that it can be CTFE'd. A more problematic case:
> ---
> void main()
> {
> immutable n = __ctfe ? 1 : 2;
> int[n] a;
> assert(a.length == n); // fails, wat
> }
ie, seeing the declaration 'int[n] a;' one should not assume a.length is same as 'n' at runtime. I would rather prefer getting a compilation error that n is not known at compile time and hence array declaration failed.
If this is eligible for a bugzilla, it is okay. Otherwise, I am very disappointed.
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply