Per Simon's suggestions in the original Contributions thread [7ac18850], here's an updated version of the ASSERT
patch.
Note: the attached patch deletes trailing whitespace from the cobc and libcob changelogs.
What is ASSERT
?
For the last few weeks, I've been slowly trying to get my head round the GNU COBOL source code, and to help me understand I've been working on adding a new statement to GNU COBOL: ASSERT
. Okay, it's another non-standard extension, but I think it will be useful.
There aren't any docs on it because this is just an extension I made up. I just liked C's assert
macro and thought it would be neat to implement a COBOL version. I don't expect this to be integrated into GNU COBOL.
ASSERT
tests a condition; if it is false, EC-IMP-FAILED-ASSERT
is raised, the location of the failed assertion is displayed on stderr
and the program terminates. The ASSERT
syntax diagram is:
ASSERT
conditional-expression
[WITH
MESSAGE
literal-1] [FOR
DEBUGGING
]
,
where literal-1
is a string. The MESSAGE
clause is used to define a message which will be displayed with the ASSERT
location and the DEBUGGING
clause specifies that the ASSERT
will only be active if the compiler switch ‑fdebug‑assert
is present. If -fsource-location
is used, FUNCTION EXCEPTION-LOCATION
is used to show the location of a failed ASSERT
. If not, the displayed location is just the file and line number. Using -debug
implicity sets -fsource-location
and -fdebug-assert
.
There is one known bug: if only the MESSAGE
clause is used and the program is compiled without -fsource-location
, the assertion's location will be one line further down than it should be.
Why would I want to use ASSERT
?
Standard COBOL programming style favours large programs which are difficult to test, which makes modifying them difficult. ASSERT
documents assumptions that you make when writing code—things you always expect to be true. Such things might be "a month has 31 days at most", "the name field will not be blank" or "the year will not be greater than 2000". Assertions help when modifying code as it allows you to say with confidence "This change has not broken this module." If you change something and an assertion fails, you then know that you have broken the code and (hopefully) how you have done it. And, when you find a bug, you can use ASSERT
s to make sure it never happens again and/or to find the source of the bad data causing it.
An equivalent, standard-conforming copybook
But what if you like assertions, but not non-standard extensions? In that case, COPY
comes to the rescue:
IF NOT ( cond ) RAISE EXCEPTION EC-USER-FAILED-ASSERT DISPLAY FUNCTION EXCEPTION-LOCATION " " message UPON STDERR STOP RUN RETURNING 1 END-IF
Using the above copybook provides the same functionality, while remaining standard-conforming. Here's how it's used:
COPY assert REPLACING ==cond== BY ==year-num < 2000== ==message== BY =="Help! Year >= 2000!"==
For assertions which should only be used for debugging, use the following copybook and >>DEFINE debug-assert
to activate:
>>IF debug-assert IS DEFINED IF NOT ( cond ) RAISE EXCEPTION EC-USER-FAILED-ASSERT DISPLAY FUNCTION EXCEPTION-LOCATION " " message UPON STDERR STOP RUN RETURNING 1 END-IF >>END-IF
Discussion: 7ac18850
Discussion: All the new reserved words, expectations
Just to add the information from the referenced Discussion:
First: the patch is very well done.
[...]
The bad news: even if the patch is that good I'm not positive to integrate it for now as there is a non-standard (even in view of "other vendors") extension that can be coded in standard ways already (with not much more code) - as the alternate COPY shows.
Simon
I'd like to re-open this ticket as I've found out that
ASSERT
has actually been implemented! In particular, Elastic COBOL has anASSERT
statement. It is defined on page 300 of their language reference:*
*
You should give that reference a read---the sheer number of extensions makes Micro Focus' reference look lean and simple.Last edit: Simon Sobisch 2019-01-27
I like this feature. Voting to accept.
I'm ok with implementing it as support for this specific elastic extension. The reserved word list will have to take care if "ASSERT" is available or not and the actication of runtime checks
-debug
will take care if there's an actual code generation.So Edward: you are free to implement this "embedded
IF
+ optionalDISPLAY
depending on runtime checks feature any time.