This snipped shows some strange behavoir:
import std.digest.crc;
import std.exception;
enum buggy1 = foo("Hello World!");
enum buggy2 = crc32Of("Hello World!");
ubyte[4] foo(string str)
{
ubyte[4] result = str.crc32Of();
enforce (result != (ubyte[4]).init, "this should not be thrown");
return result;
}
When we look at `buggy2` the error message is hinting four times at some uninitialized variable, although we don't know where exactly that is:
main.d(5): Error: uninitialized variable 'value' cannot be returned from CTFE
main.d(5): Error: uninitialized variable 'value' cannot be returned from CTFE
main.d(5): Error: uninitialized variable 'value' cannot be returned from CTFE
main.d(5): Error: uninitialized variable 'value' cannot be returned from CTFE
Now in the case of `buggy1` we do the same inside foo(), but check the result in the next line. It shows that although CTFE knows it cannot complete the crc32Of() call it continues on with a default initialized `result`:
/opt/dmd-2.066/import/std/bitmanip.d(1796): Error: Integer constant expression expected instead of void
/opt/dmd-2.066/import/std/bitmanip.d(1796): Error: Integer constant expression expected instead of void
/opt/dmd-2.066/import/std/bitmanip.d(1796): Error: Integer constant expression expected instead of void
/opt/dmd-2.066/import/std/bitmanip.d(1796): Error: Integer constant expression expected instead of void
/opt/dmd-2.066/import/std/exception.d(374): Error: Uncaught CTFE exception object.Exception("this should not be thrown")
main.d(4): called from here: foo("Hello World!")
[Reproducible at least on 2.065 and 2.066]
Comment #1 by k.hara.pg — 2015-01-20T07:47:59Z
Reduced test case. Switch the error messages by -version=check.
enum buggy1 = foo("Hello World!");
ubyte[4] foo(string str)
{
uint _state = uint.max;
ubyte[4] result = nativeToLittleEndian(~_state);
version(check)
{
import std.exception;
enforce(result != (ubyte[4]).init, "this should not be thrown");
}
return result;
}
union EndianSwapper(T)
{
T value;
ubyte[T.sizeof] array;
}
auto nativeToLittleEndian(T)(T val)
{
return nativeToLittleEndianImpl(val);
}
auto nativeToLittleEndianImpl(T)(T val)
{
EndianSwapper!T es = void;
es.value = val;
return es.array;
}
Comment #2 by dlang-bot — 2019-05-22T21:27:15Z
@thewilsonator updated dlang/phobos pull request #6976 "Fix issue 13741: can't use crc at CTFE" fixing this issue:
- Fix issue 13471: can't use crc at CTFE
https://github.com/dlang/phobos/pull/6976
Comment #3 by dlang-bot — 2019-05-23T07:22:42Z
dlang/phobos pull request #6976 "Fix issue 13471: can't use crc at CTFE" was merged into master:
- 516432d185bf4ace339f7e571f1b46894e8536aa by Nicholas Lindsay Wilson:
Fix issue 13471: can't use crc at CTFE
https://github.com/dlang/phobos/pull/6976