Don't click here unless you want to be banned.

LSL Wiki : Typecast

HomePage :: PageIndex :: RecentChanges :: RecentlyCommented :: UserSettings :: You are ia360925.us.archive.org

Typecasting

Typecasting allows conversion between a value of one type to another.

Most typecasting in LSL actually involves converting values from one type to another. For example, when a string is cast to an integer, the string value is converted into a new integer value. The exception is casting between string and key, because a key is merely a specialized form of string.

We can do typecasting in one of two ways: Explicit Typecasting | Implicit Typecasting. In both cases, note that typecasting never modifies a value stored in a variable or list; rather, the result of typecasting the value is used in the rest of the expression.


Explicit Typecasting

Explicit typecasting is the process of converting between variable types by casting them in the form: (newtype)variable.

For example, to say an integer:
integer x = 5;
llSay(0, (string)x);

When converting a string to an integer, leading spaces are ignored, as are any characters after the run of digits. For example, all of the following convert to 42:
"42"
" 42" // leading spaces are ignored
"42 is the answer" // text after the number is ignored
"42,123,456" // only the first digit sequence is interpreted

All other strings convert to the value zero.

If you use explicit typecasting, the typecast will show up in the LSL bytecode. So (integer)((integer)a), will result in bytecode typecasting an integer to an integer. Which wastes cpu time and memory; which is detrimental to your script. -- BW


Implicit Typecasting

Implicit typecasts are like explicit typecasts except that the (type) notation is not actually seen; the compiler does the casting. Implicit typecasting also happens when a value is copied from a list. However, implicit typecasting can lead to unexpected behavior with mathematical operators.

Explicit typecasting is preferred over implicit typecasting, since it is often easier to see what is actually happening during the type conversion. Plus, explicit typecasting is prone to less compiler bugginess.

LSL supports two implicit typecasts:

integer to float
string
to key

Note: as of SL 1.12.3 (6), I could also typecast (string) to (vector), and vise-versa. -ziphren

Examples:
float myFloat = 1; // 1 is an integer. 
integer myInt = 3;
myFloat = myInt; // No typecasting needed.

string myString = "foobar";
key myKey = myString; 
// ^^^ No typecasting needed, but bad coding practice (key variables should always contain UUID values).

// Without implicit typecasting, this is necessary:
float myFloat = (float)1; // or float myFloat = 1.0;
integer myInt = 4;
myFloat = (float)myInt;

// With integer -> float conversion, explicit typecasting is unnecessary since precision is never lost.

Any string can be used where a key value is required, such as storing a value into a variable of type key. Note that keys can only be explicitly typecast to and from strings. To cast a value from any other type to a key, first cast it to a string.


It is important to note that some string values can be interpreted in odd ways when typecasting. One thing that catches a lot of people is an empty string ("") or a blank space (" "); both cast to the value 0 when converting from a string to an integer. Many other programming languagues have a NULL value that would be used instead, but LSL does not.

Implicit typecasting does not work with lists because lists can hold any type of value (except other lists). If a specific type of value is required in a list, it must be explicitly cast to that type or already be of that type. LSL functions (llParticleSystem and llSetPrimitiveParams) that read lists and expect specific types will not implicitly cast the list entries. This is why functions that use lists will fail to compile when passed an integer instead of a float.


Types
Comments [Hide comments/form]
Why won't using strings and keys in place of one another work properly?
-- HankRamos (2004-04-29 12:22:35)
:growls at Catherine:
Why are people so paranoid about intermingling strings and keys?

They're exactly the same things. LL simply implemented the key type to put emphasis on that the value you can pass is most likely an UUID.
I mean, we do it all the time when using llSetTexture, llPlaySound, llLoopSound and llPreloadSound. Their first argument is declared to be a key, but how many times have you passed the name of a texture or sound there, instead of its key, more then once at least!

Also, the implicit typecasting system of LSL supports my argument. strings are understood to be keys without an explicit cast.
-- ChristopherOmega (2004-04-29 15:24:20)
Incorrect. Proof:

key k;
llSay(0, "Try this" + k);
-- EzharFairlight (2004-04-29 17:07:27)
See, Chris? You describe the way it should work, but it doesn't. There are cases in which explicit typecasting is necessary, (string-to-integer, for instance) and cases where it is not. (as in some integer-to-float or most key-to-string cases) However, implicit typecasting doesn't work all the time, that's why I avoid using it. Explicit typecasting works in all cases, and makes the code easier to read at a glance. (string)my_key makes it easier to tell if the writer's intent is to typecast than my_key. It's a matter of context -- anyone should be able to figure out an implicit typecast by looking at the code, but explicit typecasting means that you don't need to look at anything more than what's there.

For example: llSetPrimitiveParams and llParticleSystem die horribly if you try to feed them integers in place of floats.

Hank: they won't work properly because there's no UUID in the system named "hello".
-- CatherineOmega (2004-04-29 18:41:55)
Right, Ezhar, strings are understood as keys, not the other way around :-p
You can do this:

string str = "foo";
key k = str; No typcasting needed here!
llSay(0, (string)k);
Object will say "foo", the value in k is not converted to NULL_KEY immediately, since the system doesnt check if keys are valid unless it wants to.

One thing I dont understand is why LL didnt allow key -> string implicits.

The system doesnt check if anything stored in a key variable is not really a key, unless it actually needs to look up the key. LL already relies on this because they have declared llSetTexture's arguments as keys. They rely on the ability to pass say "MyTexture" in the key variable to the texture lookup code, which converts the key to a string, checks if it is a real key, and if not, checks in the object's inventory for a texture named "MyTexture". That last step wouldnt be possible if the system immediately converted "MyTexture" into NULL_KEY when it was assigned to the key variable.

Ive been neglecting going into llSetPrimativeParams and llParticleSystem. Im sort of a list-parameter-o-phobic, since the default values for things havent been published.
I dont understand why they would die if you pass an int instead of a float... if it was a float instead of an int, I'd understand, but 1 should be interpreted as 1.0 when floats are requested all the time...
Lists are quirky. They shouldnt have type-specific behavior.
You should be able to get <0,0,1> from a llList2Vector on a list element that's a valid vector, just as a string, ex: "<0,0,1>", but oddly enough, you currently cant.
-- ChristopherOmega (2004-04-30 00:04:16)
Attach a comment to this page: