How to generically initialize a value type with its default value?
Asked Answered
C

1

4

In the context of Java's Project Valhalla, how can I generically initialize a value type with its default value?

Initially, I thought that assigning null to any value type would perform this initialization. However, the answers and comments to this question clearly show that null is a reference, so it has nothing to do with value types (precisely due to the fact that value types are not references, but direct values instead).

E.g. if I have a Person value type with StringValueType name and DateValueType dateOfBirth attributes (here dateOfBirth would be a nested value type containing int year, int month and int day attributes), how could I initialize my Person value type in a generic way so that the values of its attributes are "" for name and (0, 0, 0) (or the corresponding default value) for dateOfBirth, respectively?

To make it more clear, if this were C, I would do:

memset(myPersonStructVariable, 0, sizeof(Person));

Or in modern C:

struct Person myPersonStructVariable = {0};
Cantilena answered 9/2, 2018 at 15:44 Comment(8)
@FedericoPeraltaSchaffner I don't think it's tied to a specific release. Maybe we need a new tag for future versions of java (e.g. java-soon™)Orangeman
Well, my intention was to actually know about the plan of Valhalla release ;) On the other hand, I preferably like this question more than the previous one, linked to it.Devaney
@JornVernee I love the java-soon™ tagCantilena
@JornVernee As a community member, I believe the valhalla tag is good enough and can later be tied to its release version if a corresponding tag exists. Would request you both(@Federico) to take some time to improve the tag info instead. :)Devaney
@nullpointer I'm not clear about the schedule. In many places I've read that the target was java 10, but on the other hand, the next release is expected for next March, we're almost there... I think we need an expert to clarify here ;)Cantilena
@FedericoPeraltaSchaffner this very much sounds like the vdefault would be something like an identity in case of a reduce...Hit
@Hit the identity depends on the reduction operation, i.e. for int it's 0 for sum but 1 for multiplication, so I think it's going to be used when you declare the VT without initializing it.Cantilena
@FedericoPeraltaSchaffner of course, I was just saying that it reminds me of identity, not that it is identity.Hit
O
6

The value type equivalent of the aconst_null bytecode (i.e. null, which would be the default for reference types), is the vdefault bytecode. From the minimal value type spec:

6.5 vdefault

Operation

Push the default value of a direct value class type

Format

vdefault indexbyte1 indexbyte2

...

Description

The unsigned indexbyte1 and indexbyte2 are used to construct an index into the run-time constant pool of the current class (2.6), where the value of the index is (indexbyte1 << 8) | indexbyte2. The run-time constant pool item at that index must be a symbolic reference to a direct value class type (4.4.1). The type is resolved (5.4.3.1).

The named class is initialized (5.5) if that class has not already been initialized. The default value (2.3.5) of the direct value class type is pushed onto the operand stack.

And 2.3.5:

2.3.5 Direct Value Class Types

...

The default value of a direct value class type is a class instance whose fields store the default values of their respective types. There is no special null value of a direct value class type.

And a quote from this presentation says:

[A default value] which is really a value of the right width, with all 0s inside.

So that would be similar to what you do in C with memset(myStructVar, 0, size).


There is currently no language support for value types, so we can not say if there will be something like a null literal that would return the default value of a value type (e.g. MyValueType x = default(MyValueType) or something like that), but the byte code exists. The presentation also shows how you'd use method handles to invoke vdefault. Alternatively, you'd have to spin bytecode.

Initializing fields to a user defined value (e.g. "" for StrinValueType) would probably just happen through calling a constructor (or a value type equivalent). But it really isn't clear at this point in time, so we can only speculate.


Also, check out the latest draft for the valhalla vm prototype here: http://mail.openjdk.java.net/pipermail/valhalla-dev/2017-December/003631.html

Orangeman answered 9/2, 2018 at 15:53 Comment(1)
I tried the latest build of valhalla, and did something really simple, like static value class Person { private final int x; // constructor for x } and then Person [] p = new Person[2]; p[0] = new Person(42); System.out.println(Arrays.toString(p)); I got back two nulls :) I don't know how to interpret thatHit

© 2022 - 2024 — McMap. All rights reserved.