%SIZE
Taille en octets
Renvoie le nombre d'octets qu'une zone, un tableau ou une structure de données occupe en mémoire.
Syntaxe
%SIZE(zone)
%SIZE(tableau : *ALL)
zone- Une zone, un tableau, une structure de données, une sous-zone, ou une constante.
*ALL- Pour un tableau : la taille de tous les éléments, au lieu de celle d'un seul. Pour un tableau
dim(*auto), c'est celle des éléments en cours. - Résultat
- Un entier : la taille en octets. C'est une valeur fixe, qui ne dépend pas du contenu de la zone (voir le piège pour
varchar).
À quoi ça sert
On s'en sert quand une API, un tampon ou un fichier veut une longueur en octets : la taille d'une structure de données à passer en paramètre, la place occupée par un tableau. Elle suit la déclaration : si on change une longueur, la valeur suit.
Exemple 1 : Tailles des types courants
**free
// %SIZE : nombre d'octets occupes en memoire par une zone.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-s nom char(12);
dcl-s montant packed(7:2);
dcl-s grand packed(8:2);
dcl-s zone zoned(7:2);
dcl-s petit int(5);
dcl-s entier int(10);
dcl-s jour date;
dcl-s heure time;
dcl-s horo timestamp;
snd-msg 'char(12) : ' + %char(%size(nom));
snd-msg 'packed(7:2) : ' + %char(%size(montant));
snd-msg 'packed(8:2) : ' + %char(%size(grand));
snd-msg 'zoned(7:2) : ' + %char(%size(zone));
snd-msg 'int(5) : ' + %char(%size(petit));
snd-msg 'int(10) : ' + %char(%size(entier));
snd-msg 'date : ' + %char(%size(jour));
snd-msg 'time : ' + %char(%size(heure));
snd-msg 'timestamp : ' + %char(%size(horo));
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
char(12) : 12
packed(7:2) : 4
packed(8:2) : 5
zoned(7:2) : 7
int(5) : 2
int(10) : 4
date : 10
time : 8
timestamp : 26
Un char(12) occupe 12 octets, un zoned(7:2) 7. Un décimal condensé, lui, occupe moins que son nombre de chiffres : packed(7:2) fait 4 octets, packed(8:2) 5. Les entiers font 2 octets pour int(5) et 4 pour int(10), et une date, une heure et un horodatage 10, 8 et 26.
Exemple 2 : Zones variables, tableaux et structures
**free
// %SIZE : zones variables, tableaux et structures de donnees.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-s libelle varchar(10);
dcl-s villes char(12) dim(5);
dcl-s noms varchar(20) dim(*auto : 7);
dcl-ds client qualified;
numcli packed(5:0);
nom char(20);
ville char(12);
end-ds;
libelle = 'Lyon';
snd-msg 'varchar(10) : size ' + %char(%size(libelle)) + ', len ' + %char(%len(libelle));
// Tableau : un element, ou le tableau entier avec *ALL.
snd-msg 'villes : un element ' + %char(%size(villes)) +
', total ' + %char(%size(villes : *all));
// dim(*auto) : *ALL suit le nombre d'elements en cours.
snd-msg 'noms vide : total ' + %char(%size(noms : *all));
noms(*next) = 'Dupont SA';
noms(*next) = 'Leroy SARL';
snd-msg 'noms 2 elem : un element ' + %char(%size(noms)) +
', total ' + %char(%size(noms : *all));
// Structure de donnees : somme des sous-zones (3 + 20 + 12).
snd-msg 'client : ' + %char(%size(client)) + ', dont nom ' + %char(%size(client.nom));
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
varchar(10) : size 12, len 4
villes : un element 12, total 60
noms vide : total 0
noms 2 elem : un element 22, total 44
client : 35, dont nom 20
Un varchar(10) occupe 12 octets, qu'il contienne « Lyon » ou rien du tout, alors que %len donne 4. Pour un tableau, %size donne un élément (12) et %size(… : *all) l'ensemble (60). Avec dim(*auto), *all suit le contenu : 0 à vide, 44 avec deux éléments de 22 octets. Une structure de données fait la somme de ses sous-zones : 3 + 20 + 12 = 35.
Le piège
La taille n'est ni le nombre de chiffres ni la longueur du contenu. Un packed(7:2) fait 4 octets, pas 7. Un varchar(10) en fait 12 : 10 pour le contenu au maximum, plus 2 pour la longueur. %size renvoie 12 même quand la zone contient « Lyon » ; pour la longueur du contenu, on utilise %len.
Et sur un tableau, sans *all, on n'obtient que la taille d'un élément.