Limitations Not Expressible in the Type System
Contents
An interesting edge-case in ABAP.
READ-ONLY Addition
Whereas access to attributes of a class is more conventionally controlled by member visibility (public/protected/private), ABAP has another option: the READ-ONLY
addition. This addition allows an attribute to be read from outside the class, but not altered, somewhat like if there was a getter for the attribute but no setter.
|
|
Pointers
ABAP also has pointers:
|
|
If you squint, you can kinda, sorta see how the pointer syntax resembles C. The likeness is move obvious when the fields of a structure are accessed via a pointer:
|
|
As is typical, the pointer does not include any concept of access restriction. If you have the pointer, you can access and alter the referenced value as you please; if a method returns a pointer to a private attribute, anyone with the pointer can alter the value without restrictions. If you want to control access to a value or otherwise provide encapsulation, you create a class to wrap the value and to enforce invariants.
Combining READ-ONLY and Pointers
What if we combine the write-protected READ-ONLY
attributes and pointers? Since pointers don’t in any way model access restrictions, the combination will at the very least be interesting:
|
|
The above compiles, but will produce the following rare exception when run:

Overwriting a protected field
(I especially like the Error analysis part)
This is a perfectly sane result, since I think crashing is preferable to subtly corrupting data via unintended accesses. It also highlights the fact that the type system in ABAP cannot detect this type of error statically: since read-only and read-write pointers are not separate types, all otherwise valid pointer accesses will be accepted by the compiler. At runtime, however, some pointers cannot in fact be used for writes, crashing the program.
Less of an edge-case, accessing a constant in the same manner also produces the same error:
|
|
Which is more or less how the same would work in C (though here we knowingly cast the pointer to discard the const
qualifier):
|
|
Which, when run, produces the informative error (or, I guess, we are lucky it produces this error. For all I know, this could be another instance of undefined behavior):
Bus error: 10
Obviously it would be preferable that the type system would catch these errors also, but it’s not the gravest sin since write-protected pointers are an exception rather than a frequent occurrence. But that, of course, makes these errors all the more cryptic when they are encountered once in a blue moon (“What even is a ‘protected field’?").