| Register | FAQ | Calendar | Search | Today's Posts | Mark Forums Read |
|
#31
| |||
| |||
| robin wrote: (snip, I wrote) >>It I is negative, and it isn't checked, then bad things will >>happen. Probably it should always be checked, though. > It's something that should be checked automatically. It should be, but many people like to turn off checks when their program (seems to be) debugged. Java is a rare language that requires bounds checking. I consider this related to bounds checking, though it isn't so obvious. -- glen |
|
#32
| |||
| |||
| Paul Green wrote: > "Peter Flass" <Peter_Flass@Yahoo.com> wrote in message > news:485b83e5$0$5738$4c368faf@roadrunner.com... >> wrote: >>>> VOS PL/I does not provide the stringrange condition. >> This is surprising. Since you check lengths to do the truncation on >> assignment, how much more difficult would it be to raise STRINGSIZE? >> OTOH, it's been this way since Methuzela, and you probably wouldn't wnt >> to change it now. > > I don't know. It has been this way for 28 years and I think this is the > first serious discussion I've ever had about the absence of STRINGSIZE. It > is certainly true that we'd have to be careful about breaking existing code. > Customers tend to assume that if their code runs without generating > exceptions then it must be correct...they sometimes get rather upset when we > add new checks for latent defects. They usually settle down after a while, > when they realize we've actually done them a favor. ;-) Lately I try never to post comments without checking the standard, I've been bitten too many times by thinking I have a complete understanding of how PL/I works. Probably the reason you don't have STRINGSIZE and STRINGRANGE is that they aren't in the subset G standard because they're considered "debugging conditions" along with NAME and SUBSCRIPTRANGE. .... > > The language requires an expression use to calculate an extent to be valid > any time the extent is referenced. So if you pass "A" by reference, or > assign to A, or take the length of A, etc., then the value of "i*6" must be > valid at each of these points. There is no need for the compiler to > remember the allocation length; the burden is on the source program and the > programmer. This is what I wanted to check. This just didn't sound right to me. References are from the Subset G standard. 6.3.3 Prologue "This operation is invoked at the beginning of every block activation..." Step 2.1 "...Perform EVALUATE-DATA-DESCRIPTION-FOR-ALLOCATION(dd) to obtain an <evaluated-data-description>, edd." 7.3.5 Evaluate-data-description-for-allocation Step 1.1 "Let the chosen <extent-expression> be ee. Evaluate ee by performing EVALUATE-EXPRESSION-TO-INTEGER(e) where e is the <expression> of ee, to obtain the value i. The <expression> of the <extent-expression> is replaced by an <integer-value> with the value i." (apologies for the lack of appropriate metabrackets.) As I read this, "i*6" in my example is evaluated once on entry to the block, and thereafter the declaration "CHAR(i*6)" is treated the same as if "i*6" had been a constant, that is, "i" is not referenced again, and any changes to "i" don't affect the declared extent. Your statement is true for declarations containing the "<refer option>." (As I read the standard, and also assuming I have the syntax correct, I don't often use REFER). If you say "DECLARE a char(4096 REFER(j))," then the actual length of "a" will always be determined by getting the value of "j" whenever "a" is referenced. > > However, the compiler does need to do some work behind the scenes when an > array or string with expression extents is passed as an argument, because it > is not feasible to have separately-compiled code know how to evaluate an > expression in the context of its caller. Therefore, when an argument with > expression-extents is passed to a subroutine or function, our implementation > creates a descriptor (aka "dope-vector") for it. That step effectively > makes a temporary copy of the value "i*6" and passes it as a hidden > argument. The receiving code knows how to find it. If the standard doesn't specify otherwise,and I'm not going to look just now, presumably "i" can be modified unexpectedly at any time, for example by an ON-Unit, thus changing the length -- if this were a "REFER". Isn't PL/I wonderful;-) If the world was > simple, we'd just pass a descriptor for every argument, which would double > the number of arguments (this is what Multics PL/I did, for example). The > VOS PL/I world is not that simple, but the concept is the same. Worse. If my last thought is correct, you need to pass a pointer to the "refer" variable to use for each reference. ** Posted from http://www.teranews.com ** |
|
#33
| |||
| |||
| "Peter Flass" <Peter_Flass@Yahoo.com> wrote in message news:ed64c$485fa4d9$26280@news.teranews.com... > Paul Green wrote: > > "Peter Flass" <Peter_Flass@Yahoo.com> wrote in message > > news:485b83e5$0$5738$4c368faf@roadrunner.com... > >> wrote: > >>>> VOS PL/I does not provide the stringrange condition. > >> This is surprising. Since you check lengths to do the truncation on > >> assignment, how much more difficult would it be to raise STRINGSIZE? > >> OTOH, it's been this way since Methuzela, and you probably wouldn't wnt > >> to change it now. > > > > I don't know. It has been this way for 28 years and I think this is the > > first serious discussion I've ever had about the absence of STRINGSIZE. It > > is certainly true that we'd have to be careful about breaking existing code. > > Customers tend to assume that if their code runs without generating > > exceptions then it must be correct...they sometimes get rather upset when we > > add new checks for latent defects. They usually settle down after a while, > > when they realize we've actually done them a favor. ;-) > > Lately I try never to post comments without checking the standard, I've > been bitten too many times by thinking I have a complete understanding > of how PL/I works. Probably the reason you don't have STRINGSIZE and > STRINGRANGE is that they aren't in the subset G standard because they're > considered "debugging conditions" along with NAME and SUBSCRIPTRANGE. > > The language requires an expression use to calculate an extent to be valid > > any time the extent is referenced. So if you pass "A" by reference, or > > assign to A, or take the length of A, etc., then the value of "i*6" must be > > valid at each of these points. There is no need for the compiler to > > remember the allocation length; the burden is on the source program and the > > programmer. > > This is what I wanted to check. This just didn't sound right to me. > References are from the Subset G standard. > > 6.3.3 Prologue "This operation is invoked at the beginning of every > block activation..." > Step 2.1 "...Perform EVALUATE-DATA-DESCRIPTION-FOR-ALLOCATION(dd) to > obtain an <evaluated-data-description>, edd." > > 7.3.5 Evaluate-data-description-for-allocation > Step 1.1 "Let the chosen <extent-expression> be ee. Evaluate ee by > performing EVALUATE-EXPRESSION-TO-INTEGER(e) where e is the <expression> > of ee, to obtain the value i. The <expression> of the > <extent-expression> is replaced by an <integer-value> with the value i." > (apologies for the lack of appropriate metabrackets.) > > As I read this, "i*6" in my example is evaluated once on entry to the > block, and thereafter the declaration "CHAR(i*6)" is treated the same as > if "i*6" had been a constant, that is, "i" is not referenced again, and > any changes to "i" don't affect the declared extent. That is as I understand it. |
|
#34
| |||
| |||
| "glen herrmannsfeldt" <gah@ugcs.caltech.edu> wrote in message news:v96dnXuLLJGQ_8LVnZ2dnUVZ_rjinZ2d@comcast.com. .. > robin wrote: > (snip, glen herrmannsfeldt wrote) > > >>It I is negative, and it isn't checked, then bad things will > >>happen. Probably it should always be checked, though. > > > It's something that should be checked automatically. > > It should be, but many people like to turn off checks > when their program (seems to be) debugged. When I say "automatically" I do mean "automatically". That means that the check cannot be turned off. |
|
#35
| |||
| |||
| robin wrote: > "glen herrmannsfeldt" <gah@ugcs.caltech.edu> wrote in message > news:v96dnXuLLJGQ_8LVnZ2dnUVZ_rjinZ2d@comcast.com. .. >>robin wrote: >>(snip, glen herrmannsfeldt wrote) >>>>It I is negative, and it isn't checked, then bad things will >>>>happen. Probably it should always be checked, though. >>>It's something that should be checked automatically. >>It should be, but many people like to turn off checks >>when their program (seems to be) debugged. > When I say "automatically" I do mean "automatically". > That means that the check cannot be turned off. Sounds good, but as far as I know, PL/I doesn't require that it not be turned off. -- glen |
|
#36
| |||
| |||
| "Peter Flass" wrote: > Paul Green wrote: >> The language requires an expression use to calculate an extent to be >> valid any time the extent is referenced. So if you pass "A" by >> reference, or assign to A, or take the length of A, etc., then the value >> of "i*6" must be valid at each of these points. There is no need for the >> compiler to remember the allocation length; the burden is on the source >> program and the programmer. > > This is what I wanted to check. This just didn't sound right to me. > References are from the Subset G standard. [ reference to Subset G omitted ] > As I read this, "i*6" in my example is evaluated once on entry to the > block, and thereafter the declaration "CHAR(i*6)" is treated the same as > if "i*6" had been a constant, that is, "i" is not referenced again, and > any changes to "i" don't affect the declared extent. I think I misunderstood your original claim, for which I apologize. I didn't realize you were speaking of an AUTOMATIC or DEFINED variable with expression extents. The rules vary by storage class. I agree that when the compiler goes to allocate an automatic variable with expression extents, it can evaluate the extent during the prologue, allocate the variable to that size, remember the size of the variable in a temporary, and be done with it. Similar rules apply for DEFINED; the extents are calculated and frozen at block entry. I was thinking of a BASED variable. In this case, the expression extent is evaluated every time it is needed. See 7.7.5, evaluate-data-description-for-reference. > Your statement is true for declarations containing the "<refer option>." > (As I read the standard, and also assuming I have the syntax correct, I > don't often use REFER). If you say "DECLARE a char(4096 REFER(j))," then > the actual length of "a" will always be determined by getting the value of > "j" whenever "a" is referenced. My reading of Subset G says that the REFER option can only be used within a structure or union, and the right-hand component of the REFER option is constrained to reference a member of the same structure or union, and that the only storage class that can use REFER is BASED. See validate-declaration (4.7.1) and the rules that it invokes. Your example would be valid if it was rewritten as follows: dcl 1 s based, 2 j bin, 2 a char (4096 refer (j)); REFER can only be used within a structure (or union) and the associated variable that holds the extent must be a member of the same structure. The left-hand expression of the refer is used to calculate the amount of storage to allocate and the right-hand variable is used to hold the amount that was allocated. The compiler initializes the right-hand variable to the value of the left-hand expression. Once the storage has been allocated the left-hand expression is free to change. See allocate-based-storage (7.3.2). Full PL/I (X3.53) allows multiple instances of REFER to occur in the same structure. Subset G does not. PG |
|
#37
| |||
| |||
| Peter Flass wrote: > > If the standard doesn't specify otherwise,and I'm not going to look just > now, presumably "i" can be modified unexpectedly at any time, for > example by an ON-Unit, thus changing the length -- if this were a > "REFER". Isn't PL/I wonderful;-) > Not so. The refer option is used to create "self describing" based variables. Here is a simple example which covers the situation you are discussing. Source: %process mar(2,100); test: proc options(main) reorder; dcl (a,b) char(10) var, (p,q,r) ptr, 1 s based, 2 l bin fixed(15), 2 c char(length(a)+length(b)+1 refer(l)), sysprint file print, length builtin; a='good'; b='morning'; allocate s set(p); p->c=a||' '||b; b='afternoon'; allocate s set(q); q->c=a||' '||b; do r=p,q; put file(sysprint) edit(length(r->c),'|',r->c,'|') (col(1),f(3),x(1),3 a); end; end test; Output: 12 |good morning| 14 |good afternoon| Discussion: As the example illustrates, several instances of a based variable can exist simultaneously. Each instance must have its own pointer. Different instances of the string s.c can have different lengths. The REFER option provides the mechanism for keeping track of the lengths of the individual instances. When an instance of s is allocated, the expression length(a)+length(b)+1 is evaluated to determine the length of c; enough space is allocated for l and c; and the length of c is stored in l. This is the only time the expression is evaluated for this instance of s. On all other references to this instance, the value of l is used to determine the length of c. Changing the value of variables on which the expression depends has no effect on the length of c in an existing instance of s. Changing the value of an instance of s.l is, of course, a nono; doing so can lead to memory corruption. A based structure or union can include multiple instances of the REFER option to deal with variable string sizes, array bounds, or area sizes. |
|
#38
| |||
| |||
| Sounds all good to me. You're right about REFER, as I said, I don't use it much. Paul Green wrote: > "Peter Flass" wrote: > >>Paul Green wrote: >> >>>The language requires an expression use to calculate an extent to be >>>valid any time the extent is referenced. So if you pass "A" by >>>reference, or assign to A, or take the length of A, etc., then the value >>>of "i*6" must be valid at each of these points. There is no need for the >>>compiler to remember the allocation length; the burden is on the source >>>program and the programmer. >> >>This is what I wanted to check. This just didn't sound right to me. >>References are from the Subset G standard. > > > [ reference to Subset G omitted ] > > >>As I read this, "i*6" in my example is evaluated once on entry to the >>block, and thereafter the declaration "CHAR(i*6)" is treated the same as >>if "i*6" had been a constant, that is, "i" is not referenced again, and >>any changes to "i" don't affect the declared extent. > > > I think I misunderstood your original claim, for which I apologize. > > I didn't realize you were speaking of an AUTOMATIC or DEFINED variable with > expression extents. The rules vary by storage class. I agree that when the > compiler goes to allocate an automatic variable with expression extents, it > can evaluate the extent during the prologue, allocate the variable to that > size, remember the size of the variable in a temporary, and be done with it. > Similar rules apply for DEFINED; the extents are calculated and frozen at > block entry. > > I was thinking of a BASED variable. In this case, the expression extent is > evaluated every time it is needed. See 7.7.5, > evaluate-data-description-for-reference. > > >>Your statement is true for declarations containing the "<refer option>." >>(As I read the standard, and also assuming I have the syntax correct, I >>don't often use REFER). If you say "DECLARE a char(4096 REFER(j))," then >>the actual length of "a" will always be determined by getting the value of >>"j" whenever "a" is referenced. > > > My reading of Subset G says that the REFER option can only be used within a > structure or union, and the right-hand component of the REFER option is > constrained to reference a member of the same structure or union, and that > the only storage class that can use REFER is BASED. See > validate-declaration (4.7.1) and the rules that it invokes. > > Your example would be valid if it was rewritten as follows: > > dcl 1 s based, > 2 j bin, > 2 a char (4096 refer (j)); > > REFER can only be used within a structure (or union) and the associated > variable that holds the extent must be a member of the same structure. The > left-hand expression of the refer is used to calculate the amount of storage > to allocate and the right-hand variable is used to hold the amount that was > allocated. The compiler initializes the right-hand variable to the value of > the left-hand expression. Once the storage has been allocated the left-hand > expression is free to change. See allocate-based-storage (7.3.2). > > Full PL/I (X3.53) allows multiple instances of REFER to occur in the same > structure. Subset G does not. > > PG > > ** Posted from http://www.teranews.com ** |
|
#39
| |||
| |||
| James J. Weinkam wrote: > When an instance of s is allocated, the > expression length(a)+length(b)+1 is evaluated to determine the length of > c; enough space is allocated for l and c; and the length of c is stored > in l. Interesting. This is one use of REFER that hadn't occurred to me. You can always learn something new, even about a language you've used for forty years. ** Posted from http://www.teranews.com ** |
|
#40
| |||
| |||
| "glen herrmannsfeldt" <gah@ugcs.caltech.edu> wrote in message news:HqidnUKilKNISP3VnZ2dnUVZ_oWdnZ2d@comcast.com. .. > robin wrote: > > > "glen herrmannsfeldt" <gah@ugcs.caltech.edu> wrote in message > > news:v96dnXuLLJGQ_8LVnZ2dnUVZ_rjinZ2d@comcast.com. .. > > >>robin wrote: > >>(snip, glen herrmannsfeldt wrote) > > >>>>It I is negative, and it isn't checked, then bad things will > >>>>happen. Probably it should always be checked, though. > > >>>It's something that should be checked automatically. > > >>It should be, but many people like to turn off checks > >>when their program (seems to be) debugged. > > > When I say "automatically" I do mean "automatically". > > That means that the check cannot be turned off. > > Sounds good, but as far as I know, PL/I doesn't > require that it not be turned off. That's irrelevant. PL/I doesn't specify what happens should such a value occur. It's up to the implementor to deal with it sensibly. As this particular problem is virtually unrecoverable, it's important that it be detected by the implementor and handled properly, as suggested. |
![]() |
| Thread Tools | |
| Display Modes | |
In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.