How to check if an array is a manifest constant?

Jonathan M Davis jmdavisProg at gmx.com
Mon Apr 4 03:34:49 PDT 2011


On 2011-04-04 03:11, simendsjo wrote:
> > What use case do you have for wanting to know whether a variable is an
> > enum or not?
> 
> The same reason I'd like to check if it's const/immutable; if an algorithm
> requires a modifiable array.
> 
> void sortInPlace(int[] array) {
>     array.sort;
> }
> 
> void main() {
>     int[] a = [3,2,1];
>     sortInPlace(a);
>     assert(a == [1,2,3]);
> 
>     auto i = [3,2,1].idup;
>     //sortInPlace(i); // Fails at compile time
> 
>     enum e = [3,2,1];
>     sortInPlace(e);
>     assert(e == [1,2,3]); // fails at runtime
> }
> 
> I can check the type for const or immutable with template constraits or
> static if's, but I cannot check for enum.
> I can use ref int[] as a parameter to get a compile time error, but that's
> misleading as I often don't want to reassign the parameter.
> 
> Cannot the type of enum e = [1] be immutable(int[])? Or is that wrong?
> Or am I missing something crucial because of CTFE or other stuff? I've just
> started looking into D2, so theres a good possibility my reasoning is
> wrong.

Apparently, part of the point of using enums is to have them be replaced with 
the value without having any kind of address. So, they're _supposed_ to be a 
copy and therefore don't have to be const or immutable.

Generally, it should be clear whether a function alters its arguments or not. 
You can't use const or immutable arrays with a function which alters its array 
argument or the elements of its array argument, because the array itself can't 
be altered. In the case of enums, it _can_ be altered, because when you use 
it, you get a copy. It literally copies and pastes the value of the enum where 
you use it. So, there's _nothing_ wrong with passing an enum which is an array 
to a function which alters the elements of its array argument. It's perfectly 
legal. It's just generally a bad idea, since it's a temporary.

There's no need to check whether a function's argument is an enum anymore than 
there's a need to check whether the argument is a temporary. Both are 
perfectly legal, just generally pointless. If a slice of the array is returned 
or saved in a global variable or whatnot, then it's not pointless. But if it's 
just altering the function's argument, then it is. But the function doesn't 
need to worry about it. It's still perfectly legal. It's up to the caller to 
actually pass an array that's worth altering. And since the function should be 
clear on whether it alters its arguments, it shouldn't be a problem that it's 
up to the caller to use it correctly with regards to temporaries and enums - 
just like it's up to the caller not to be stupid and pass any other array that 
it doesn't actually want to alter.

So, really there's no reason to stop an enum from working with a function that 
alters the elements of an array. All temporaries have the same issue. If you 
really want to prevent it, then just make the argument a ref. It also makes it 
clear that you're altering the array. If you don't want to make it a ref, then 
just make the documentation clear, and it's up to the caller to use the 
function appropriately. For instance, it should be obvious to the caller that 
passing an enum to a function like sortInPlace would be just stupid.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list