www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - isMutable doesn't work with enum ?

reply "Temtaime" <temtaime gmail.com> writes:
Hi!

	enum int a = 5;
	writeln(isMutable!(typeof(a)));

Writes true. Why? How i can figure out if variable is "enum" 
constant ?
Thanks.
Regards.
Jun 02 2013
next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, June 03, 2013 00:14:34 Temtaime wrote:
 Hi!
 
 	enum int a = 5;
 	writeln(isMutable!(typeof(a)));
 
 Writes true. Why? How i can figure out if variable is "enum"
 constant ?
 Thanks.
 Regards.
isMutable just checks whether the type const or immutable, and is true if it's neither. And int is mutable. Also, what you've declared there is a manifest constant, not really an enum in the normal sense. It would have to have a type name for it be a full-on enum. Something more like enum E : int { a = 5 } Your a there is not typed as an enum at all. The difference between it and doing something like immutable int a = 5; is the fact a manifest constant does not have an address and gets copy-pasted where it's used, which is why doing something like enum arr = [1, 2, 3, 4, 5]; is often considered a bad idea. An array gets allocated every time that the manifest constant is used, because using arr effectively just pastes [1, 2, 3, 4, 5] in its place. However, if you really want to check whether something is an enum or not, do is(E == enum) And with your original definition, is(typeof(a) == enum) will be false, because its type is int. - Jonathan M Davis
Jun 02 2013
parent reply "Temtaime" <temtaime gmail.com> writes:
It's intresting.
So the only way to pass "a" to overloaded function like that ?

void foo(T)(ref T) { writeln("true"); }
void foo(T)(auto ref in T) { writeln("false"); }

enum int a = 10;
foo(a); // false

int b = 1;
foo(b); // true
Jun 02 2013
next sibling parent reply "Temtaime" <temtaime gmail.com> writes:
I'm writing serializer and it iterates all members of struct.
It compares fields marked as "enum" when reading from file to 
check BOM, for example.

I'm using enum now because const members are deprecated in 2.063.
Jun 02 2013
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, June 03, 2013 00:36:46 Temtaime wrote:
 I'm writing serializer and it iterates all members of struct.
 It compares fields marked as "enum" when reading from file to
 check BOM, for example.
 
 I'm using enum now because const members are deprecated in 2.063.
The equivalent to what const members were doing before is static const. static was being implicitly tacked onto the const. enums do something subtley different. static const variables are actually variables with addresses (lvalues), whereas enums have no address and are rvalues. - Jonathan M Davis
Jun 02 2013
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, June 03, 2013 00:34:49 Temtaime wrote:
 It's intresting.
 So the only way to pass "a" to overloaded function like that ?
 
 void foo(T)(ref T) { writeln("true"); }
 void foo(T)(auto ref in T) { writeln("false"); }
 
 enum int a = 10;
 foo(a); // false
 
 int b = 1;
 foo(b); // true
ref only accepts lvalues. An enum is not an lvalue. auto ref makes it so that if the templated function is passed an lvalue, it generates a ref version, whereas if it's passed an rvalue, it generates a non-ref version. It would appear that the compiler considers ref to be a better match than auto ref (as opposed to giving an error), so when you pass foo an lvalue, the ref version gets called, but when you pass it an rvalue, the only viable overload is the auto ref one, so it gets called. - Jonathan M Davis
Jun 02 2013
prev sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Temtaime:

 	enum int a = 5;
 	writeln(isMutable!(typeof(a)));

 Writes true. Why?
If you run this: enum int a = 5; pragma(msg, typeof(a)); void main() {} It prints "int". An int is mutable.
 How i can figure out if variable is "enum" constant ?
Why do you need to know that? Bye, bearophile
Jun 02 2013