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