# Vectors changes, to avoid a trap with modifying a temporary value

**URL:** <https://forum.castle-engine.io/t/vectors-changes-to-avoid-a-trap-with-modifying-a-temporary-value/522>\
**Category:** News\
**Created:** [February 11, 2022, 6:05pm UTC](https://forum.castle-engine.io/t/vectors-changes-to-avoid-a-trap-with-modifying-a-temporary-value/522 "2022-02-11T18:05:02Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![michalis](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/michalis/32/3_2.png) [@michalis](https://forum.castle-engine.io/u/michalis)\
**Post date:** [February 11, 2022, 6:05pm UTC](https://forum.castle-engine.io/t/vectors-changes-to-avoid-a-trap-with-modifying-a-temporary-value/522/1 "2022-02-11T18:05:02Z")

</div>

| [![Cthulhu high-poly model (4.5 million triangles) in glTF by TooManyDemons](https://castle-engine.io/wp/wp-content/uploads/2022/02/cthulhu-200x113.png)](https://castle-engine.io/wp/wp-content/uploads/2022/02/cthulhu.png "Cthulhu high-poly model (4.5 million triangles) in glTF by TooManyDemons") |

We have made a significant change to how our vectors are declared. They now have `X`, `Y`, `Z`, `W` as fields (not properties), and the compiler will prevent you from falling into a trap of writing

```
Scene.Translation.X := Scene.Translation.X + 10;
```

Like in the below testcase:

```
uses SysUtils, CastleScene, CastleVectors;
var
  S: TCastleScene;
begin
  S := TCastleScene.Create(nil);
  S.Translation.X := S.Translation.X + 10;
  FreeAndNil(S);
end.
```

This has always been invalid code, as it potentially modifies a temporary value, not the actual `Scene.Translation` value. And even if it modifies the actual `Scene.Translation` value (under some optimization/compiler version), it bypasses the `Scene.Translation` property setter. This is documented in-depth in [coding traps](https://castle-engine.io/coding_traps) documentation page.

I recognized this was a significant trap when using CGE vectors, and changed the way vector is declared to make it impossible. From now on, this code will no longer compile. FPC prevents us from making this mistake.

This affects all our vectors and colors:

- `TVector2`, `TVector3`, `TVector4`,

- `TCastleColor`, `TCastleColorRGB`,

- `TVector2Double`, `TVector3Double`, `TVector4Double`,

- `TVector2Byte`, `TVector3Byte`, `TVector4Byte`,

- `TVector2Integer`, `TVector3Integer`, `TVector4Integer`,

- `TVector2Cardinal`, `TVector3Cardinal`, `TVector4Cardinal`.

The change is _mostly_ backward compatible (if your code was safe).

- Some properties and methods remain as deprecated (so they will compile, for now, albeit with clear warning from a compiler): `Data`, `Items` properties,methods `Init` and `NormalizeMe`. We will completely remove them at some point in the future (we don’t like traps in API 🙂 ) so please follow the compiler warnings and adjust your code to not use them.

- Setting fields `X`, `Y`, `Z`, `W` is now the only way to change the vector “in place” that works reliably and is not deprecated.

- `V[0]` works but is read-only now. It is equivalent to `V.X` or `V.AsArray[0]`.

- Constructions that treat `Data` as an array will no longer work, as it is now an indexed property. So `V1.Data := V2.Data` should change to just `V1 := V2`.

- `Data` is no longer a direct field, so `V.Data[0] += 2` will no longer work. Change it to `V.X += 2`. If you really need by-index access, you can temporarily change it to `V.Data[0] := V.Data[0] + 2` or `V.InternalData[0] := V.InternalData[0] + 2` — these provide a quick upgrade path, although we recommend avoiding such constructions altogether in new code.

- Constant declarations will need to change. `Foo: TVector3 = (Data: (1, 2, 3))` should now be `Foo: TVector3 = (X: 1; Y: 2; Z: 3)`.

The other records in CGE will soon follow with a similar redesign. The only way to change the record “in place” is by direct field access, not by some method or property setter. This means that compiler will prevent invalid operations. This applies to:

- `TMatrix2`, `TMatrix3`, `TMatrix4`,

- `TBox3D`,

- `TQuaternion`,

- `TTriangle`.

P.S. As usual with such posts, I had trouble selecting a screenshot. How do you visualize “vector API cleanup”? 🙂 So here’s a screenshot of [view3dscene](https://castle-engine.io/view3dscene.php) rendering [glTF model](https://castle-engine.io/gltf) of [Cthulhu (model by TooManyDemons, distributed on SketchFab)](https://sketchfab.com/3d-models/cthulhu-6d05f0957cfc4a3bba2aaa01d58acbd9). The model is quite high-poly, done in ZBrush (4.5 million triangles, but it’s just s single mesh and it renders with 60 FPS).
