Jump to content
Main menu
Main menu
move to sidebar
hide
Navigation
Main page
Recent changes
Random page
Help about MediaWiki
Special pages
Niidae Wiki
Search
Search
Appearance
Create account
Log in
Personal tools
Create account
Log in
Pages for logged out editors
learn more
Contributions
Talk
Editing
COBOL
(section)
Page
Discussion
English
Read
Edit
View history
Tools
Tools
move to sidebar
hide
Actions
Read
Edit
View history
General
What links here
Related changes
Page information
Appearance
move to sidebar
hide
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
===Procedure division=== ====Procedures==== The sections and paragraphs in the procedure division (collectively called procedures) can be used as [[label (programming)|labels]] and as simple [[subroutines]]. Unlike in other divisions, paragraphs do not need to be in sections.{{sfn|ISO/IEC JTC 1/SC 22/WG 4|2014|loc=§ 14.4}} Execution goes down through the procedures of a program until it is terminated.{{sfn|ISO/IEC JTC 1/SC 22/WG 4|2014|loc=§ 14.6.3}} To use procedures as subroutines, the {{code|PERFORM}} verb is used. A {{code|PERFORM}} statement somewhat resembles a procedure call in a newer languages in the sense that execution returns to the code following the {{code|PERFORM}} statement at the end of the called code; however, it does not provide a mechanism for [[Parameter (computer programming)|parameter passing]] or for returning a result value. If a subroutine is invoked using a simple statement like {{code|PERFORM subroutine|lang=cobolfree}}, then control returns at the end of the called procedure. However, {{code|PERFORM}} is unusual in that it may be used to call a range spanning a sequence of several adjacent procedures. This is done with the {{code|PERFORM sub-1 THRU sub-n|lang=cobolfree}} construct: <syntaxhighlight lang="cobolfree"> PROCEDURE so-and-so. PERFORM ALPHA PERFORM ALPHA THRU GAMMA STOP RUN. ALPHA. DISPLAY 'A'. BETA. DISPLAY 'B'. GAMMA. DISPLAY 'C'. </syntaxhighlight> The output of this program will be: "A A B C". {{code|PERFORM}} also differs from conventional procedure calls in that there is, at least traditionally, no notion of a call stack. As a consequence, nested invocations are possible (a sequence of code being {{code|PERFORM}}'ed may execute a {{code|PERFORM}} statement itself), but require extra care if parts of the same code are executed by both invocations. The problem arises when the code in the inner invocation reaches the exit point of the outer invocation. More formally, if control passes through the exit point of a {{code|PERFORM}} invocation that was called earlier but has not yet completed, the COBOL 2002 standard stipulates that the behavior is [[Undefined behavior|undefined]]. The reason is that COBOL, rather than a "return address", operates with what may be called a continuation address. When control flow reaches the end of any procedure, the continuation address is looked up and control is transferred to that address. Before the program runs, the continuation address for every procedure is initialized to the start address of the procedure that comes next in the program text so that, if no {{code|PERFORM}} statements happen, control flows from top to bottom through the program. But when a {{code|PERFORM}} statement executes, it modifies the continuation address of the called procedure (or the last procedure of the called range, if {{code|PERFORM THRU}} was used), so that control will return to the call site at the end. The original value is saved and is restored afterwards, but there is only one storage position. If two nested invocations operate on overlapping code, they may interfere which each other's management of the continuation address in several ways.<ref name="FR99">{{cite conference | url=http://pages.cs.wisc.edu/~ramali/Papers/paste99.pdf |archive-url=https://web.archive.org/web/20101224060615/http://pages.cs.wisc.edu/~ramali/Papers/paste99.pdf |archive-date=24 December 2010 |url-status=live | title=Identifying Procedural Structure in Cobol Programs | doi=10.1145/381788.316163 | first1=John | last1=Field | first2=G. | last2=Ramalingam | conference=PASTE '99 | isbn=1581131372 | conference-url=http://cseweb.ucsd.edu/~wgg/paste99.html | date=September 1999}}</ref><ref name="VV07">{{cite journal | url=http://www.cs.vu.nl/~nveerman/research/minefield/minefield.pdf | title=Cobol minefield detection | journal=Software: Practice and Experience |date=November 2006 | volume=36 | issue=14 | doi=10.1002/spe.v36:14 | archive-url=https://web.archive.org/web/20070306135410/http://www.cs.vu.nl/~nveerman/research/minefield/minefield.pdf | url-status=dead | archive-date=6 March 2007 | last1=Veerman | first1=Niels | last2=Verhoeven | first2=Ernst-Jan | s2cid=18619757 }}</ref> The following example (taken from {{harvnb|Veerman|Verhoeven|2006}}) illustrates the problem: <syntaxhighlight lang="cobolfree"> LABEL1. DISPLAY '1' PERFORM LABEL2 THRU LABEL3 STOP RUN. LABEL2. DISPLAY '2' PERFORM LABEL3 THRU LABEL4. LABEL3. DISPLAY '3'. LABEL4. DISPLAY '4'. </syntaxhighlight> One might expect that the output of this program would be "1 2 3 4 3": After displaying "2", the second {{code|PERFORM}} causes "3" and "4" to be displayed, and then the first invocation continues on with "3". In traditional COBOL implementations, this is not the case. Rather, the first {{code|PERFORM}} statement sets the continuation address at the end of {{code|LABEL3}} so that it will jump back to the call site inside {{code|LABEL1}}. The second {{code|PERFORM}} statement sets the return at the end of {{code|LABEL4}} but does not modify the continuation address of {{code|LABEL3}}, expecting it to be the default continuation. Thus, when the inner invocation arrives at the end of {{code|LABEL3}}, it jumps back to the outer {{code|PERFORM}} statement, and the program stops having printed just "1 2 3". On the other hand, in some COBOL implementations like the open-source TinyCOBOL compiler, the two {{code|PERFORM}} statements do not interfere with each other and the output is indeed "1 2 3 4 3". Therefore, the behavior in such cases is not only (perhaps) surprising, it is also not portable.<ref name="VV07"/> A special consequence of this limitation is that {{code|PERFORM}} cannot be used to write recursive code. Another simple example to illustrate this (slightly simplified from {{harvnb|Veerman|Verhoeven|2006}}): <syntaxhighlight lang="cobolfree"> MOVE 1 TO A PERFORM LABEL STOP RUN. LABEL. DISPLAY A IF A < 3 ADD 1 TO A PERFORM LABEL END-IF DISPLAY 'END'. </syntaxhighlight> One might expect that the output is "1 2 3 END END END", and in fact that is what some COBOL compilers will produce. But other compilers, like IBM COBOL, will produce code that prints "1 2 3 END END END END ..." and so on, printing "END" over and over in an endless loop. Since there is limited space to store backup continuation addresses, the backups get overwritten in the course of recursive invocations, and all that can be restored is the jump back to {{code|DISPLAY 'END'}}.<ref name="VV07"/> ====Statements==== COBOL 2014 has 47 statements (also called ''{{dfn|verbs}}''),{{sfn|ISO/IEC JTC 1/SC 22/WG 4|2014|loc=§ 14.9}} which can be grouped into the following broad categories: control flow, I/O, data manipulation and the report writer. The report writer statements are covered in the [[#Report writer|report writer section]]. =====Control flow===== COBOL's [[conditional (computer programming)|conditional statements]] are {{code|IF}} and {{code|EVALUATE}}. {{code|EVALUATE}} is a [[switch statement|switch-like statement]] with the added capability of evaluating multiple values and conditions. This can be used to implement [[decision table]]s. For example, the following might be used to control a [[CNC lathe]]: <!-- a more common appliance would be more suitable. --> <syntaxhighlight lang="cobolfree"> EVALUATE TRUE ALSO desired-speed ALSO current-speed WHEN lid-closed ALSO min-speed THRU max-speed ALSO LESS THAN desired-speed PERFORM speed-up-machine WHEN lid-closed ALSO min-speed THRU max-speed ALSO GREATER THAN desired-speed PERFORM slow-down-machine WHEN lid-open ALSO ANY ALSO NOT ZERO PERFORM emergency-stop WHEN OTHER CONTINUE END-EVALUATE </syntaxhighlight> The {{code|PERFORM}} statement is used to define loops which are executed {{em|until}} a condition is true (not {{em|while}} true, which is more common in other languages). It is also used to call procedures or ranges of procedures (see the [[#Procedures|procedures section]] for more details). {{code|CALL}} and {{code|INVOKE}} call subprograms and methods, respectively. The name of the subprogram/method is contained in a string which may be a literal or a data item.{{sfn|ISO/IEC JTC 1/SC 22/WG 4|2014|loc=§§ 14.9.4, 14.9.22}} Parameters can be passed [[call by reference|by reference]], by content (where a copy is passed by reference) or [[call by value|by value]] (but only if a [[function prototype|prototype]] is available).{{sfn|ISO/IEC JTC 1/SC 22/WG 4|2014|loc=§ D.6.5.2.2}} {{code|CANCEL}} unloads subprograms from memory. {{code|GO TO}} causes the program to jump to a specified procedure. The {{code|GOBACK}} statement is a [[return statement]] and the {{code|STOP}} statement stops the program. The {{code|EXIT}} statement has six different formats: it can be used as a return statement, a [[break statement]], a [[continue statement]], an end marker or to leave a procedure.{{sfn|ISO/IEC JTC 1/SC 22/WG 4|2014|loc=§ 14.9.13.1}} [[Exception handling|Exceptions]] are raised by a {{code|RAISE}} statement and caught with a handler, or ''{{dfn|declarative}}'', defined in the {{code|DECLARATIVES}} portion of the procedure division. Declaratives are sections beginning with a {{code|USE}} statement which specify the errors to handle. Exceptions can be names or objects. {{code|RESUME}} is used in a declarative to jump to the statement after the one that raised the exception or to a procedure outside the {{code|DECLARATIVES}}. Unlike other languages, uncaught exceptions may not terminate the program and the program can proceed unaffected. =====I/O===== File I/O is handled by the self-describing {{code|OPEN}}, {{code|CLOSE}}, {{code|READ}}, and {{code|WRITE}} statements along with a further three: {{code|REWRITE}}, which updates a record; {{code|START}}, which selects subsequent records to access by finding a record with a certain key; and {{code|UNLOCK}}, which releases a [[lock (database)|lock]] on the last record accessed. User interaction is done using {{code|ACCEPT}} and {{code|DISPLAY}}. =====Data manipulation===== The following verbs manipulate data: * {{code|INITIALIZE}}, which sets data items to their default values. * {{code|MOVE}}, which [[assignment (computer science)|assigns]] values to data items ; ''MOVE CORRESPONDING'' assigns corresponding like-named [[Record (computer science)#COBOL|fields]]. * {{code|SET}}, which has 15 formats: it can modify indices, assign object references and alter table capacities, among other functions.{{sfn|ISO/IEC JTC 1/SC 22/WG 4|2014|loc=§14.9.35.1}} * {{code|ADD}}, {{code|SUBTRACT}}, {{code|MULTIPLY}}, {{code|DIVIDE}}, and {{code|COMPUTE}}, which handle arithmetic (with {{code|COMPUTE}} assigning the result of a formula to a variable). * {{code|ALLOCATE}} and {{code|FREE}}, which handle [[dynamic memory]]. * {{code|VALIDATE}}, which validates and distributes data as specified in an item's description in the data division. * {{code|STRING}} and {{code|UNSTRING}}, which [[Concatenation|concatenate]] and split [[string (computer science)|string]]s, respectively. * {{code|INSPECT}}, which tallies or replaces instances of specified [[substring]]s within a string. * {{code|SEARCH}}, which searches a table for the first entry satisfying a condition. Files and tables are sorted using {{code|SORT}} and the {{code|MERGE}} verb merges and sorts files. The {{code|RELEASE}} verb provides records to sort and {{code|RETURN}} retrieves sorted records in order. ====Scope termination==== Some statements, such as {{code|IF}} and {{code|READ}}, may themselves contain statements. Such statements may be terminated in two ways: by a period (''{{dfn|implicit termination}}''), which terminates ''all'' unterminated statements contained, or by a scope terminator, which terminates the nearest matching open statement. <syntaxhighlight lang="cobolfree"> *> Terminator period ("implicit termination") IF invalid-record IF no-more-records NEXT SENTENCE ELSE READ record-file AT END SET no-more-records TO TRUE. *> Scope terminators ("explicit termination") IF invalid-record IF no-more-records CONTINUE ELSE READ record-file AT END SET no-more-records TO TRUE END-READ END-IF END-IF </syntaxhighlight> Nested statements terminated with a period are a common source of bugs.{{sfn|ISO/IEC JTC 1/SC 22/WG 4|2014|p=899}}{{sfn|McCracken|Golden|1988|loc=§ 8.4}} For example, examine the following code: <syntaxhighlight lang="cobolfree"> IF x DISPLAY y. DISPLAY z. </syntaxhighlight> Here, the intent is to display <code>y</code> and <code>z</code> if condition <code>x</code> is true. However, <code>z</code> will be displayed whatever the value of <code>x</code> because the <code>IF</code> statement is terminated by an erroneous period after {{code|DISPLAY y|lang=cobolfree}}. Another bug is a result of the [[dangling else problem]], when two <code>IF</code> statements can associate with an <code>ELSE</code>. <syntaxhighlight lang="cobolfree"> IF x IF y DISPLAY a ELSE DISPLAY b. </syntaxhighlight> In the above fragment, the <code>ELSE</code> associates with the {{code|IF y|lang=cobolfree}} statement instead of the {{code|IF x|lang=cobolfree}} statement, causing a bug. Prior to the introduction of explicit scope terminators, preventing it would require {{code|ELSE NEXT SENTENCE|lang=cobolfree}} to be placed after the inner <code>IF</code>.{{sfn|McCracken|Golden|1988|loc=§ 8.4}} ====Self-modifying code==== The original (1959) COBOL specification supported the infamous {{code|ALTER X TO PROCEED TO Y|lang=cobolfree}} statement, for which many compilers generated [[self-modifying code]]. <code>X</code> and <code>Y</code> are procedure labels, and the single {{code|GO TO|lang=cobolfree}} statement in procedure <code>X</code> executed after such an {{code|ALTER}} statement means {{code|GO TO Y|lang=cobolfree}} instead. Many compilers still support it,<ref>Examples of compiler support for {{code|ALTER}} can be seen in the following: * {{cite web|ref=none |last=Tiffin |first=Brian |title=September 2013 |url=http://sourceforge.net/p/open-cobol/discussion/cobol/thread/7dc2941f/#5ee9 |work=GNU Cobol |date=18 September 2013 |access-date=5 January 2014 |archive-url=https://web.archive.org/web/20140505181734/http://sourceforge.net/p/open-cobol/discussion/cobol/thread/7dc2941f/ |archive-date=5 May 2014 |url-status=dead }} * {{cite web|ref=none |url=http://documentation.microfocus.com/help/topic/com.microfocus.eclipse.infocenter.visualcobol.vs2013/HRLHLHPDF803.html |title=The ALTER Statement |publisher=Micro Focus |work=Micro Focus Visual COBOL 2.2 for Visual Studio 2013 COBOL Language Reference |access-date=5 January 2014 }} * {{cite web|ref=none |url=http://www.csim.scu.edu.tw/~kuo/COBOL/COBOLCompiler/COBOL%E6%89%8B%E5%86%8A/cob_lrf.pdf |title=ALTER Statement (Nucleus) |publisher=Fujitsu |work=COBOL85 Reference Manual |date=November 1996 |access-date=5 January 2014 |page=555 |archive-url=https://web.archive.org/web/20140106031540/http://www.csim.scu.edu.tw/~kuo/COBOL/COBOLCompiler/COBOL%E6%89%8B%E5%86%8A/cob_lrf.pdf |archive-date=6 January 2014 |url-status=dead }} * {{cite web|ref=none |url=http://pic.dhe.ibm.com/infocenter/pdthelp/v1r1/topic/com.ibm.entcobol.doc_5.1/PGandLR/ref/rlpsalte.html |title=ALTER Statement |publisher=IBM |work=Enterprise COBOL for z/OS Language Reference |date=June 2013 |access-date=5 January 2014 }}</ref> but it was deemed [[deprecation|obsolete]] in the COBOL 1985 standard and deleted in 2002.{{sfn|ISO/IEC JTC 1/SC 22/WG 4|2001|loc=§ F.1}} The {{code|ALTER}} statement was poorly regarded because it undermined "locality of context" and made a program's overall logic difficult to comprehend.{{sfn|McCracken|1976|p=355}} As textbook author [[Daniel D. McCracken]] wrote in 1976, when "someone who has never seen the program before must become familiar with it as quickly as possible, sometimes under critical time pressure because the program has failed ... the sight of a GO TO statement in a paragraph by itself, signaling as it does the existence of an unknown number of ALTER statements at unknown locations throughout the program, strikes fear in the heart of the bravest programmer."{{sfn|McCracken|1976|p=355}}
Summary:
Please note that all contributions to Niidae Wiki may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
Encyclopedia:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Search
Search
Editing
COBOL
(section)
Add topic