Jass Primitive Types

From WarCraft3

< wc3
Jump to: navigation, search

In computer science, a primitive type is a data type for which the programming language provides built-in support.

In case of Jass, there is a total of 6 primitive data types - integer, real, string, boolean, code and handle.

Contents

integer

integer is the simplest data type. Jass uses 32-bit signed integers represented using two's-complement arithmetic. In other words, integer in Jass is the same as long in C.

Some examples of valid integers in Jass:

local integer a = 5              //  5
local integer b = 2+3            //  5
local integer c = a+3            //  8
local integer d = 19/10          //  1
local integer e = R2I(19.0/10.0) //  1
local integer f = S2I("5")       //  5
local integer g = 010            //  8
local integer h = 0x10           // 16
local integer i = 'a'            // 97
local integer j = 'abcd'         // 1633837924
  • Variable d is an example of division. Jass truncates when dividing integers by other integers.
  • Variable e is actually real division (to be covered later) and an example of converting the real to integer using R2I.
  • Variable f is a string conversion using S2I.
  • Variable g is an octal number.
  • Variable h is a hexadecimal number
  • Variable i is an ASCII character.
  • Variable j is a combination of 4 ASCII characters, used mostly for Raw codes of units and abilities. More on this follows.

Raw codes

While GUI has special types such as UnitType and Ability, these are all in fact integers in Jass.

How this works? Lets take a look as hfoo for example (Footman). ASCII values of 'h', 'f' and 'o' are 104 (0x68), 102 (0x66) and 111 (0x6F) respectively. From that point, there are two methods we can use to convert this into the actual integer (in case of hfoo 1751543663).

  • Method 1 - simply replace each letter in hfoo with its respective hexadecimal value - you'll get 0x68666F6F which, converted to decimal, equals 1751543663.
  • Method 2 - if you aren't that familiar with hexadecimal numbers - 1751543663=(((104)*256+102)*256+111)*256+111.

real

Jass uses 32-bit floating points for its real variables - these are equivalent to float in C. Their precision is up to 3 digits - the expression 0.0001 == 0.00 will always be true.

Some examples of valid reals in Jass:

local real a = 5.00           //  5.000
local real b = 5.             //  5.000
local real c = S2R("5.0")     //  5.000
local real d = I2R(5)         //  5.000
local real e = 5              //  5.000
local real f = 19/10          //  1.000
local real g = 19./10.        //  1.900
  • Variable c is a string conversion using S2R.
  • Variable d is an integer conversion using I2R. Variable e is the same, but the conversion is implicit. Therefore, using 5. as opposed to 5 is recommended as the latter is slower (requires a conversion).
  • Variable f is also an implicit conversion from an integer - since both 19 and 10 are integers (because there is no decimal symbol), it is parsed as integer division and then converted to real.
  • Variable g is the proper way to do real division.

string

In C, all strings are in fact arrays of character and a "string" type is simply the pointer to the first character in that array. Jass strings are slightly different - the "pointer to the first character" concept remains, but the actual pointers are indexes for an internal string table. Therefore, Jass strings can be considered smart pointers.

Every string you use has to be allocated and stored somewhere in the memory. But when one string occurs more than once, it's a waste to allocate more memory since you already have it stored somewhere. The string table basically makes sure you never have two same strings stored in the memory. Here are some examples of valid strings along with whether using them will allocate memory (under the assumption there are no strings present in the table at the time this code is ran):

local string a = "foo" // "foo" allocated
local string b = "bar" // "bar" allocated
local string c = "foobar" // "foobar" allocated
local string d = a+b // "foobar" reused
local string e = I2S(50) // "50" allocated
local string f = "50" // "50" reused

This code includes 6 variables, but allocates a total of 4 strings. This can easily be proven using a return bug function GetStringId:

function GetStringId takes string s returns integer
    return s
    return 0
endfunction

Using this function on the previously declared variables will return a total of 4 different numbers - GetStringId(c) and GetStringId(d) will return the same number. Same goes for GetStringId(e) and GetStringId(f).

boolean

boolean in Jass is 32-bit although in most cases its value will be either true or false (1 or 0). A conditional statement like this

if (boolvar) then
    call BJDebugMsg("yes")
else
    call BJDebugMsg("no")
endif

will display "yes" if the boolean boolvar has any value other than zero. However a boolexpr filter will only consider booleans with the value of 1 as true - this becomes a problem with the IsUnitType function which sometimes returns 64 instead of 1 due to a bug.

code

code is a data type used for storing function references and it is most likely a 32-bit integer. Since it's rarely used, very little is known about it. It is used by several functions such as TimerStart and ForGroup. code is also the only known type that can't be used for an array.

handle

handle is a 32-bit integer smart pointer reference to an object. It is the primitive type from which all other types defined in common.j extend from. The actual type is largely unused in Jass - common.j does not contain a single native that takes or returns a handle. The handle type can, however, be useful in cases where polymorphism is needed, the most notable example being H2I.

It is known that Jass implements reference counting so that handles of destroyed objects can be reused later. This is why all local handle variables (or local variables of any type that extends from handle) should be set to null before the end of a function.

local timer t1 = CreateTimer() // creates a handle and sets reference count to 1
local timer t2 = t1            // another variable now points to the same timer - reference count becomes 2
call DestroyTimer(t1)          // the timer is destroyed, but it's handle still has two references
set t1 = null                  // reference count is now 1
set t2 = null                  // reference count is now 0 - the handle is recycled
Personal tools