Intrinsic Functions
|
This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. The reference material consulted while preparing these pages is listed in the section bibliography. |
This page is written against ISO/IEC 1989:2023 (edition 3, January 2023; a 4th edition is upcoming), GnuCOBOL 3.2 and IBM
Enterprise COBOL for z/OS 6.5, checked on 2026-10-20. Every program below was compiled with cobc -x -Wall (GnuCOBOL 3.2.0)
and run, both with the default dialect and with -std=ibm, and compiled without warnings. The deliberately wrong ones
show the real diagnostics. The examples use the Circulation library scenario of this section: the BOOKREC copybook,
member names, loan counts and fines.
An intrinsic function is a function that the compiler supplies, so it needs no declaration in the DATA DIVISION. It
computes a value from its arguments each time it is referenced, and that value can be used wherever a data item of the
same kind is allowed. Intrinsic functions entered COBOL with an amendment to the 1985 standard (the GnuCOBOL manual
describes its COBOL-85 mode as that standard plus the intrinsic-function amendment, and nothing else), and later
standards added more. This page shows how to call them, how to read the six categories, the conversion, math and
size functions you will use most, and then lists all of them. Dates and times (CURRENT-DATE, INTEGER-OF-DATE and
their relatives) are worked through on Dates and Times, the string
functions (TRIM, UPPER-CASE, REVERSE, SUBSTITUTE) next to STRING and UNSTRING on
STRING, UNSTRING and INSPECT, national and UTF-8
functions on National Data, UTF-8 and Code Pages, and
functions that you write yourself on
User-Defined Functions and Prototypes.
Calling a function
A function reference is the reserved word FUNCTION, the function name and, for most functions, a list of arguments in
parentheses. Enterprise COBOL’s Language Reference gives the general format as:
FUNCTION function-name-1 [ ( argument-1 ... ) ] [ ( reference-modifier ) ]
The rules that matter in daily work:
-
A function reference stands for the value it returns, so it can appear where a data item of that kind is allowed: as the sending item of
MOVE, inDISPLAY, in a condition, in an arithmetic expression, or as an argument of another function. It can never be a receiving item, and it cannot be passedBY REFERENCEon aCALL. -
An argument is a data item, an arithmetic expression, another function reference, a special register, or a literal. Figurative constants such as
SPACEorZEROare not allowed. A group item stands in for an alphanumeric argument. -
Arguments are separated by spaces. A separator comma (a comma followed by a space) can be used anywhere a space can, and GnuCOBOL accepted it between arguments. If an expression argument starts with a unary plus or minus, the expression must be immediately preceded by a left parenthesis.
-
Nested functions are evaluated on their own, from the innermost out, and the arguments of one function are evaluated from left to right.
-
Reference modification (
item(start:length)) is allowed on the result of an alphanumeric or national function, and is applied to the returned value. -
A function that takes no argument is written without parentheses (
FUNCTION CURRENT-DATE,FUNCTION PI).
The result of a function belongs to one of five types: alphanumeric, national, UTF-8, numeric or integer. A numeric
function cannot be used where an integer operand is required, even when its value happens to be whole; INTEGER and
INTEGER-PART force the type. Some functions change type with their arguments: SUM, MAX and MIN return an integer
when all arguments are integers and a numeric value otherwise, and MAX and MIN can even return an alphanumeric or
national value when given such arguments.
The program below uses a few of those rules at once: a function as the sending item, reference modification of a result, and function and expression arguments in the same list.
IDENTIFICATION DIVISION.
PROGRAM-ID. FUNSYNTAX.
* Calling intrinsic functions: the FUNCTION keyword, nesting,
* reference modification of a result and expressions as arguments.
DATA DIVISION.
WORKING-STORAGE SECTION.
COPY BOOKREC.
01 WS-LABEL PIC X(12).
01 WS-WIDEST PIC 9(3).
01 WS-LOAN-COUNTS.
05 WS-DAY-1 PIC 9(3) VALUE 4.
05 WS-DAY-2 PIC 9(3) VALUE 9.
05 WS-DAY-3 PIC 9(3) VALUE 2.
01 WS-TOTAL PIC 9(4).
PROCEDURE DIVISION.
MAIN-PARA.
MOVE "DATA STRUCTURES" TO BOOK-TITLE
* A function-identifier is used where a data item is allowed.
DISPLAY FUNCTION UPPER-CASE(BOOK-TITLE)
DISPLAY FUNCTION LOWER-CASE(BOOK-TITLE)
* Its value can be reference-modified: first 4 characters.
MOVE FUNCTION LOWER-CASE(BOOK-TITLE)(1:4) TO WS-LABEL
DISPLAY "[" WS-LABEL "]"
* Arguments may be functions or arithmetic expressions.
COMPUTE WS-WIDEST = FUNCTION MAX((3 * 4),
FUNCTION LENGTH(WS-LABEL), FUNCTION LENGTH(BOOK-TITLE))
DISPLAY "widest: " WS-WIDEST
COMPUTE WS-TOTAL = FUNCTION SUM((WS-DAY-3 * 10),
WS-DAY-1, WS-DAY-2)
DISPLAY "total: " WS-TOTAL
STOP RUN.
Output (identical under -std=ibm):
DATA STRUCTURES
data structures
[data ]
widest: 030
total: 0033
MAX returns 30 because BOOK-TITLE is 30 characters long, and SUM adds 20 (the expression), 4 and 9. The expression
is written first in both lists on purpose, which is explained under the pitfalls below.
Dropping the FUNCTION keyword with REPOSITORY
The REPOSITORY paragraph of the CONFIGURATION SECTION makes the keyword optional. Both compilers use the same format, one
FUNCTION followed by a list of names and the word INTRINSIC, or by ALL INTRINSIC. A name listed there may be written
without the keyword, and in that scope it cannot also be used as a user-defined word. The list form below compiled and ran
under both dialects:
IDENTIFICATION DIVISION.
PROGRAM-ID. FUNREPO.
* REPOSITORY makes the FUNCTION keyword optional.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
FUNCTION UPPER-CASE TRIM LENGTH INTRINSIC.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-MEMBER-NAME PIC X(30) VALUE " Ada Lovelace".
01 WS-SIZE PIC 9(4).
PROCEDURE DIVISION.
MAIN-PARA.
DISPLAY "[" TRIM(WS-MEMBER-NAME) "]"
DISPLAY UPPER-CASE(TRIM(WS-MEMBER-NAME))
COMPUTE WS-SIZE = LENGTH(TRIM(WS-MEMBER-NAME))
DISPLAY WS-SIZE
STOP RUN.
[Ada Lovelace]
ADA LOVELACE
0012
The shortcut for all of them is FUNCTION ALL INTRINSIC., which both manuals document (GnuCOBOL can also be run with
cobc -fintrinsics=ALL, or -fintrinsics=name,name for a few). The GnuCOBOL Programmer’s Guide warns that
ALL INTRINSIC turns more than a hundred names into reserved words:
IDENTIFICATION DIVISION.
PROGRAM-ID. FUNREPOALL.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
FUNCTION ALL INTRINSIC.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-MEMBER-NAME PIC X(30) VALUE " Ada Lovelace".
PROCEDURE DIVISION.
MAIN-PARA.
DISPLAY REVERSE(TRIM(WS-MEMBER-NAME))
STOP RUN.
ecalevoL adA
Without that paragraph function names are not reserved words, so a data item may share a name with a function and the
FUNCTION keyword says which one is meant. Enterprise COBOL’s Programming Guide uses SQRT for exactly this:
IDENTIFICATION DIVISION.
PROGRAM-ID. FUNNAMES.
* Function names are not reserved words: SQRT and TRIM can also
* be data names; FUNCTION tells the compiler which one is meant.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 SQRT PIC 99 VALUE 0.
01 TRIM PIC X(5) VALUE " ab ".
PROCEDURE DIVISION.
MAIN-PARA.
COMPUTE SQRT = FUNCTION SQRT(16)
DISPLAY SQRT
DISPLAY "[" FUNCTION TRIM(TRIM) "]"
STOP RUN.
04
[ab]
(The first line prints 04 because SQRT is a two-digit item.) Use that sparingly, because with REPOSITORY in force it
stops working (see the pitfalls below). The Enterprise COBOL Language Reference adds one more rule for programs that
define their own functions: LENGTH, RANDOM, SIGN, SUM and WHEN-COMPILED cannot be reused as the name of a
user-defined function.
Subscripting a whole table with ALL
Enterprise COBOL lets the word ALL stand in for a subscript in a function argument, which expands to one argument per
table element, from the first to the last. FUNCTION MAX(Table(ALL)) is the same as FUNCTION MAX(Table(1) Table(2) ... Table(n)), several ALL subscripts expand in order with the rightmost varying fastest, and for a table with
OCCURS DEPENDING ON the range follows the current value of the controlling item. The Language Reference example reads
(z/OS; not run here):
01 PAYROLL.
02 PAYROLL-WEEK PIC 99.
02 PAYROLL-HOURS PIC 999 OCCURS 1 TO 52
DEPENDING ON PAYROLL-WEEK.
...
COMPUTE YTD-HOURS = FUNCTION SUM (PAYROLL-HOURS(ALL))
COMPUTE MAX-HOURS = FUNCTION MAX (PAYROLL-HOURS(ALL))
COMPUTE MAX-WEEK = FUNCTION ORD-MAX (PAYROLL-HOURS(ALL))
GnuCOBOL 3.2.0 does not accept this form in any dialect that was tried (the default, -std=ibm, ibm-strict, mf and
cobol2014): the compiler stops with syntax error, unexpected ALL. A portable program lists the elements, or adds them
up in a PERFORM VARYING loop. ALL only makes sense for the functions that take a variable number of arguments.
Argument types
Each function states what kind of argument it needs. The Language Reference uses these argument types:
| Type | What it accepts |
|---|---|
Alphabetic and alphanumeric |
A data item of class alphabetic or alphanumeric, an alphanumeric group, or an alphanumeric literal. The content, and sometimes the length, is used. |
National |
A national data item (or group) or literal. |
UTF-8 |
A data item or group of category UTF-8. |
DBCS |
Only |
Integer |
An arithmetic expression that always gives a whole number. |
Numeric |
An arithmetic expression: numeric literals and data items of any numeric category, including floating point. |
Keyword |
A word fixed by the function, for example |
Floating-point items and literals are accepted as numeric arguments but not where an integer is required, nor where an
alphanumeric or national argument is required (UPPER-CASE, LOWER-CASE, REVERSE, NUMVAL, NUMVAL-C). A value that
breaks a function’s own constraints (a negative SQRT argument, say) gives an undefined result, so validate input first
and use the exception facilities of
Error Handling and Declaratives. GnuCOBOL’s manual
describes the same data as a "group item, USAGE DISPLAY elementary item or alphanumeric literal" and does not split
arguments into this many types.
The six categories
Enterprise COBOL groups the functions into six categories, based on the type of service they perform. The Programming Guide also tabulates the numeric ones by use.
| Category | Typical members |
|---|---|
Mathematical |
|
Statistical |
|
Date/time |
|
Financial |
|
Character-handling |
|
General |
|
The Language Reference names the six categories but does not assign every function to one, and the Programming Guide
table "Numeric intrinsic functions" regroups the numeric ones as number handling, date and time, finance, mathematics and
statistics (it files LENGTH, MAX, MIN, NUMVAL, SIGN and ORD-MAX under number handling, for example). The
assignment in the full table below is therefore this page’s own reading, and only a navigation aid.
Numeric functions are also classified by what they return: integer functions, floating-point functions and mixed
functions that return an integer, a floating-point value or a fixed-point number depending on the arguments. With the
default ARITH(COMPAT) option the floating-point functions return long (64-bit) results; with ARITH(EXTEND) they
return extended-precision (128-bit) results, the exception being RANDOM. That matters for the money functions below,
and it is covered in more depth on Arithmetic and COMPUTE.
Converting text to numbers: NUMVAL, NUMVAL-C and NUMVAL-F
A value typed by a clerk or read from a text file rarely has the fixed shape of a PICTURE clause. NUMVAL,
NUMVAL-C and NUMVAL-F turn free-form text (an alphanumeric or national data item or literal) into a number, and
TEST-NUMVAL, TEST-NUMVAL-C and TEST-NUMVAL-F check it first.
| Function | Accepts |
|---|---|
|
Optional spaces, an optional sign before or after the digits ( |
|
The same, plus a currency string and grouping separators, such as |
|
A floating-point form with an exponent, such as |
|
Return 0 when the text is valid for the matching function, and otherwise the position of the first character in error. (Enterprise COBOL returns the length plus one when no character is wrong but the string is not a complete number.) |
With DECIMAL-POINT IS COMMA the roles of comma and point are reversed in the argument. Enterprise COBOL limits the
digits to 18 under ARITH(COMPAT) and 31 under ARITH(EXTEND), and warns that only about 15 decimal digits convert
accurately to long floating point, because the result of all three functions is a floating-point value. Compile with
ARITH(EXTEND) when an argument can carry more than 15 digits.
IDENTIFICATION DIVISION.
PROGRAM-ID. FUNNUMVAL.
* Converting free-form text to numbers: NUMVAL, NUMVAL-C,
* NUMVAL-F, with TEST-NUMVAL to validate first.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-TEXT PIC X(16).
01 WS-FINE PIC S9(5)V99.
01 WS-FINE-OUT PIC -(5)9.99.
01 WS-BAD-POS PIC 99.
PROCEDURE DIVISION.
MAIN-PARA.
* NUMVAL: optional sign (leading or trailing), spaces, CR/DB.
MOVE " 12.50" TO WS-TEXT
PERFORM SHOW-NUMVAL
MOVE "-7.25" TO WS-TEXT
PERFORM SHOW-NUMVAL
MOVE "3.10 CR" TO WS-TEXT
PERFORM SHOW-NUMVAL
MOVE "40 DB" TO WS-TEXT
PERFORM SHOW-NUMVAL
* NUMVAL-C: currency sign and thousands separators allowed.
MOVE "$1,234.50" TO WS-TEXT
COMPUTE WS-FINE = FUNCTION NUMVAL-C(WS-TEXT)
MOVE WS-FINE TO WS-FINE-OUT
DISPLAY WS-TEXT " -> NUMVAL-C " WS-FINE-OUT
* NUMVAL-F: floating-point text with an exponent.
MOVE "1.5E+2" TO WS-TEXT
COMPUTE WS-FINE = FUNCTION NUMVAL-F(WS-TEXT)
MOVE WS-FINE TO WS-FINE-OUT
DISPLAY WS-TEXT " -> NUMVAL-F " WS-FINE-OUT
* TEST-NUMVAL: 0 if valid, else the position of the error.
MOVE "12.5X" TO WS-TEXT
COMPUTE WS-BAD-POS = FUNCTION TEST-NUMVAL(WS-TEXT)
DISPLAY WS-TEXT " -> TEST-NUMVAL " WS-BAD-POS
MOVE "12.50" TO WS-TEXT
COMPUTE WS-BAD-POS = FUNCTION TEST-NUMVAL(WS-TEXT)
DISPLAY WS-TEXT " -> TEST-NUMVAL " WS-BAD-POS
STOP RUN.
SHOW-NUMVAL.
COMPUTE WS-FINE = FUNCTION NUMVAL(WS-TEXT)
MOVE WS-FINE TO WS-FINE-OUT
DISPLAY WS-TEXT " -> NUMVAL " WS-FINE-OUT.
Output (identical under -std=ibm):
12.50 -> NUMVAL 12.50
-7.25 -> NUMVAL -7.25
3.10 CR -> NUMVAL -3.10
40 DB -> NUMVAL -40.00
$1,234.50 -> NUMVAL-C 1234.50
1.5E+2 -> NUMVAL-F 150.00
12.5X -> TEST-NUMVAL 05
12.50 -> TEST-NUMVAL 00
CR and DB make the value negative, and a trailing sign works as well as a leading one. TEST-NUMVAL reported 5 for
12.5X because the fifth character is the first one that does not fit. Sources:
NUMVAL-C,
NUMVAL-F,
TEST-NUMVAL,
Programming Guide: Converting to numbers (NUMVAL, NUMVAL-C, NUMVAL-F)
and the GnuCOBOL Programmer’s Guide pages for
NUMVAL, NUMVAL-C and NUMVAL-F.
NUMVAL does not reject bad text; it quietly returns whatever it understood. In GnuCOBOL 3.2.0 12.5X gave 12.50 and
abc gave zero, with no exception and no diagnostic, so validate with TEST-NUMVAL before trusting the number:
IDENTIFICATION DIVISION.
PROGRAM-ID. SILENT.
* NUMVAL never fails: bad text gives a partial value or zero.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-TEXT PIC X(10) VALUE "12.5X".
01 WS-FINE PIC 9(3)V99.
01 WS-FINE-OUT PIC ZZ9.99.
01 WS-POS PIC 99.
PROCEDURE DIVISION.
MAIN-PARA.
COMPUTE WS-FINE = FUNCTION NUMVAL(WS-TEXT)
MOVE WS-FINE TO WS-FINE-OUT
DISPLAY WS-TEXT " NUMVAL " WS-FINE-OUT
MOVE "abc" TO WS-TEXT
COMPUTE WS-FINE = FUNCTION NUMVAL(WS-TEXT)
MOVE WS-FINE TO WS-FINE-OUT
DISPLAY WS-TEXT " NUMVAL " WS-FINE-OUT
COMPUTE WS-POS = FUNCTION TEST-NUMVAL(WS-TEXT)
DISPLAY WS-TEXT " TEST-NUMVAL " WS-POS
STOP RUN.
12.5X NUMVAL 12.50
abc NUMVAL 0.00
abc TEST-NUMVAL 01
Here TEST-NUMVAL returned 1 for abc, because the very first character is already wrong. The
Programming Guide shows the typical use: read a line into PIC X(10) and compute the number with NUMVAL, instead of
forcing the user to type a sign and the exact decimal layout of PIC S999V99 SIGN LEADING SEPARATE. The GnuCOBOL
Programmer’s Guide also mentions a LOCALE keyword for NUMVAL-C; it was not exercised for this page.
Math and statistics
The mathematical functions work on any numeric argument. Two pairs deserve care, because the names are close and the results on negative values are not what the schoolbook "remainder" suggests.
-
MOD(a, b)isa - b * INTEGER(a / b), so it takes the sign of the divisor;REM(a, b)isa - b * INTEGER-PART(a / b), so it takes the sign of the dividend.MODtakes integers;REMtakes any numeric. -
INTEGERis the greatest integer not greater than its argument (it rounds toward minus infinity), andINTEGER-PARTsimply drops the fraction.
The Language Reference tabulates MOD for 11 and 5 as 1, -11 and 5 as 4, 11 and -5 as -4, and -11 and -5 as -1. The
program below reproduces the negative cases, then runs the statistical and financial functions on a handful of daily loan
counts.
IDENTIFICATION DIVISION.
PROGRAM-ID. FUNMATH.
* Numeric functions: integer arithmetic, rounding, statistics,
* finance and the random-number generator.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-INT PIC -9(4).
01 WS-DEC PIC -9(4).9(4).
01 WS-NEG PIC S9V9 VALUE -2.5.
01 WS-WEEK.
05 WS-D1 PIC 9(3) VALUE 12.
05 WS-D2 PIC 9(3) VALUE 30.
05 WS-D3 PIC 9(3) VALUE 7.
05 WS-D4 PIC 9(3) VALUE 30.
05 WS-D5 PIC 9(3) VALUE 21.
01 WS-RATE PIC 9V9999 VALUE 0.0100.
01 WS-PERIODS PIC 99 VALUE 12.
PROCEDURE DIVISION.
MAIN-PARA.
* MOD follows the sign of the divisor, REM that of the dividend.
COMPUTE WS-INT = FUNCTION MOD(-11, 5)
DISPLAY "MOD(-11,5) = " WS-INT
COMPUTE WS-INT = FUNCTION MOD(11, -5)
DISPLAY "MOD(11,-5) = " WS-INT
COMPUTE WS-INT = FUNCTION REM(-11, 5)
DISPLAY "REM(-11,5) = " WS-INT
* INTEGER rounds down, INTEGER-PART truncates toward zero.
COMPUTE WS-INT = FUNCTION INTEGER(WS-NEG)
DISPLAY "INTEGER(-2.5) = " WS-INT
COMPUTE WS-INT = FUNCTION INTEGER-PART(WS-NEG)
DISPLAY "INTEGER-PART(-2.5) = " WS-INT
COMPUTE WS-DEC = FUNCTION SQRT(2)
DISPLAY "SQRT(2) = " WS-DEC
COMPUTE WS-DEC = FUNCTION ABS(WS-NEG)
DISPLAY "ABS(-2.5) = " WS-DEC
* Statistics over a list of arguments.
COMPUTE WS-INT = FUNCTION SUM(WS-D1, WS-D2, WS-D3,
WS-D4, WS-D5)
DISPLAY "SUM = " WS-INT
COMPUTE WS-INT = FUNCTION MAX(WS-D1, WS-D2, WS-D3,
WS-D4, WS-D5)
DISPLAY "MAX = " WS-INT
COMPUTE WS-INT = FUNCTION MIN(WS-D1, WS-D2, WS-D3,
WS-D4, WS-D5)
DISPLAY "MIN = " WS-INT
COMPUTE WS-DEC = FUNCTION MEAN(WS-D1, WS-D2, WS-D3,
WS-D4, WS-D5)
DISPLAY "MEAN = " WS-DEC
COMPUTE WS-DEC = FUNCTION MEDIAN(WS-D1, WS-D2, WS-D3,
WS-D4, WS-D5)
DISPLAY "MEDIAN = " WS-DEC
COMPUTE WS-INT = FUNCTION ORD-MAX(WS-D1, WS-D2, WS-D3,
WS-D4, WS-D5)
DISPLAY "ORD-MAX = " WS-INT
COMPUTE WS-INT = FUNCTION RANGE(WS-D1, WS-D2, WS-D3,
WS-D4, WS-D5)
DISPLAY "RANGE = " WS-INT
* Finance: instalment ratio and discounted value.
COMPUTE WS-DEC = FUNCTION ANNUITY(WS-RATE, WS-PERIODS)
DISPLAY "ANNUITY = " WS-DEC
COMPUTE WS-DEC = FUNCTION PRESENT-VALUE(WS-RATE, 100, 100)
DISPLAY "PRESENT-VAL = " WS-DEC
* Same seed, same sequence.
COMPUTE WS-DEC = FUNCTION RANDOM(42)
DISPLAY "RANDOM(42) = " WS-DEC
COMPUTE WS-DEC = FUNCTION RANDOM
DISPLAY "RANDOM next = " WS-DEC
STOP RUN.
Output (identical under -std=ibm):
MOD(-11,5) = 0004
MOD(11,-5) = -0004
REM(-11,5) = -0001
INTEGER(-2.5) = -0003
INTEGER-PART(-2.5) = -0002
SQRT(2) = 0001.4142
ABS(-2.5) = 0002.5000
SUM = 0100
MAX = 0030
MIN = 0007
MEAN = 0020.0000
MEDIAN = 0021.0000
ORD-MAX = 0002
RANGE = 0023
ANNUITY = 0000.0888
PRESENT-VAL = 0197.0395
RANDOM(42) = 0000.5692
RANDOM next = 0000.9857
Notes on the output:
-
ORD-MAXreturned 2 although 30 occurs twice (positions 2 and 4): GnuCOBOL gave the first one in this run. The Language Reference does not promise which wins, so do not depend on the tie rule. -
RANGEis the largest minus the smallest argument (30 - 7 = 23).MEDIANof five values is the middle one in sorted order (7 12 21 30 30), andMEANis 100 / 5. -
ANNUITY(rate, periods)is the ratio of a level payment to the starting amount, so 1% for 12 periods gives about 0.0888, and a loan of 500.00 would cost about 44.42 per period.PRESENT-VALUE(rate, amount ...)discounts each period-end amount: two payments of 100 at 1% are worth about 197.04 today. -
RANDOMreturns a pseudo-random number strictly between 0 and 1. The same seed gives the same sequence. The numbers are specific to the compiler (and to the release: theRANDOMalgorithm changed in GnuCOBOL 3.2): Enterprise COBOL’s Programming Guide says itsRANDOMand the Language Environment serviceCEERAN0produce different numbers from the same seed, and GnuCOBOL has yet another generator, so never compare random output across compilers. The program uses the argument only to start a sequence; if the first call has no argument, Enterprise COBOL uses a seed of zero.
Most mathematical functions have a matching Language Environment callable service on z/OS (ACOS and CEESDACS,
EXP and CEESDEXP, SQRT and CEESDSQT); the Programming Guide lists them, and states that RANDOM is the exception
because the two algorithms differ. Source:
Language Reference: RANDOM and
Language Reference: SUM.
LENGTH and BYTE-LENGTH
LENGTH returns how many character positions an argument occupies. For an alphanumeric item that is the same as its
size in bytes, for a NATIONAL item it counts national positions (a PIC 9(3) item with USAGE NATIONAL has LENGTH
3 although it needs 6 bytes), and for a group with OCCURS DEPENDING ON it is computed from the current value of the
controlling item. BYTE-LENGTH always counts bytes. The special register LENGTH OF gives the same figure for a
data item. Enterprise COBOL returns a 9-digit result with LP(32) and an 18-digit result with LP(64), so assign the result to your own
PICTURE instead of displaying it directly.
IDENTIFICATION DIVISION.
PROGRAM-ID. FUNLENGTH.
* Sizes: LENGTH, BYTE-LENGTH and the LENGTH OF special register.
* Results are moved to WS-SIZE first, so every compiler shows
* the same four digits.
DATA DIVISION.
WORKING-STORAGE SECTION.
COPY BOOKREC.
01 WS-SHELF.
05 WS-SHELF-COUNT PIC 99 VALUE 3.
05 WS-SHELF-BOOK PIC 9(6) OCCURS 1 TO 10 TIMES
DEPENDING ON WS-SHELF-COUNT.
01 WS-PACKED PIC S9(7)V99 COMP-3 VALUE 1234.5.
01 WS-SIZE PIC 9(4).
PROCEDURE DIVISION.
MAIN-PARA.
MOVE "COBOL BASICS" TO BOOK-TITLE
COMPUTE WS-SIZE = FUNCTION LENGTH(BOOK-RECORD)
DISPLAY "BOOK-RECORD " WS-SIZE
COMPUTE WS-SIZE = FUNCTION LENGTH(BOOK-TITLE)
DISPLAY "BOOK-TITLE " WS-SIZE
COMPUTE WS-SIZE = FUNCTION BYTE-LENGTH(BOOK-TITLE)
DISPLAY "BYTE-LENGTH " WS-SIZE
COMPUTE WS-SIZE = FUNCTION LENGTH(WS-PACKED)
DISPLAY "COMP-3 field " WS-SIZE
COMPUTE WS-SIZE = FUNCTION LENGTH("Circulation")
DISPLAY "literal " WS-SIZE
* A group with OCCURS DEPENDING ON is measured at run time.
COMPUTE WS-SIZE = FUNCTION LENGTH(WS-SHELF)
DISPLAY "shelf (3 books) " WS-SIZE
MOVE 10 TO WS-SHELF-COUNT
COMPUTE WS-SIZE = FUNCTION LENGTH(WS-SHELF)
DISPLAY "shelf (10 books) " WS-SIZE
* LENGTH OF is the special-register spelling of the same idea.
MOVE LENGTH OF BOOK-TITLE TO WS-SIZE
DISPLAY "LENGTH OF title " WS-SIZE
* Length of the text without trailing spaces: TRIM first.
COMPUTE WS-SIZE = FUNCTION LENGTH(FUNCTION TRIM(BOOK-TITLE))
DISPLAY "trimmed title " WS-SIZE
STOP RUN.
Output (identical under -std=ibm):
BOOK-RECORD 0060
BOOK-TITLE 0030
BYTE-LENGTH 0030
COMP-3 field 0005
literal 0011
shelf (3 books) 0020
shelf (10 books) 0062
LENGTH OF title 0030
trimmed title 0012
The packed field S9(7)V99 COMP-3 takes five bytes, the 10-entry shelf takes 2 + 10 * 6 = 62, and LENGTH(TRIM(...))
measures the text without its trailing spaces. GnuCOBOL’s LENGTH follows the same rules for alphanumeric data, and its
Programmer’s Guide adds LENGTH-AN, an alias of BYTE-LENGTH. GnuCOBOL 3.2.0 still reports warning: handling of USAGE
NATIONAL is unfinished for national data, so the national example is left to
National Data, UTF-8 and Code Pages.
LENGTH is also the only function that accepts an unbounded group (a group that ends in a table with an unbounded
OCCURS); every other function rejects such an argument.
Beyond the portable core
The functions marked "Common" in the table below exist in both compilers. Beyond them there are three groups:
-
Functions only Enterprise COBOL 6.5 has: the Unicode set
ULENGTH,UPOS,USUBSTR,USUPPLEMENTARY,UVALIDandUWIDTH, andUUID4. GnuCOBOL 3.2.0 does not know them at all (FUNCTION 'ULENGTH' unknown). -
Functions GnuCOBOL 3.2 has that Enterprise COBOL 6.5 lacks. Eleven of them are in the
-std=cobol2014word list ofcobc, so they look like standard functions that IBM did not implement: theEXCEPTION-*functions,FRACTION-PART,LOCALE-COMPARE,LOCALE-DATE,LOCALE-TIME,LOCALE-TIME-FROM-SECONDSand theHIGHEST-ALGEBRAIC/LOWEST-ALGEBRAICpair. The other 19 are GnuCOBOL extensions as far as these manuals show:CONCATENATEand its short formCONCAT,SUBSTITUTE,SUBSTITUTE-CASE,LENGTH-AN,STORED-CHAR-LENGTH,CONTENT-LENGTH, theMODULE-*functions,CURRENCY-SYMBOLand theMONETARY-*andNUMERIC-*locale functions. -
Functions both compilers implement but that GnuCOBOL’s standard-based dialects leave out:
HEX-OF,HEX-TO-CHAR,BIT-OF,BIT-TO-CHARandCONTENT-OF.-std=cobol2014and-std=cobol85rejectHEX-OFandBIT-OFas unknown. GnuCOBOL 3.2 addedBIT-OFandHEX-OF(they are in its list of new features), apparently for compatibility with Enterprise COBOL, which introducedCONTENT-OFin 6.4.
The program below mixes the second and third groups. It compiled and ran without warnings under both dialects, but
-std=ibm accepts every function name that GnuCOBOL implements, so it does not prove that Enterprise COBOL could compile
it; that is what -std=ibm-strict is for:
IDENTIFICATION DIVISION.
PROGRAM-ID. FUNVENDOR.
* Functions outside the portable core: GnuCOBOL-only and
* IBM-originated ones that GnuCOBOL 3.2 also implements.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-CODE PIC X(4) VALUE "AB1 ".
01 WS-FIRST PIC X(8) VALUE "Ada".
01 WS-LAST PIC X(12) VALUE "Lovelace".
01 WS-LINE PIC X(40).
01 WS-SIZE PIC 9(4).
PROCEDURE DIVISION.
MAIN-PARA.
* HEX-OF and BIT-OF: also in Enterprise COBOL 6.5.
DISPLAY "HEX-OF " FUNCTION HEX-OF(WS-CODE)
DISPLAY "BIT-OF " FUNCTION BIT-OF("A")
* CONCATENATE, SUBSTITUTE and LENGTH-AN: GnuCOBOL only.
MOVE FUNCTION CONCATENATE(FUNCTION TRIM(WS-FIRST), " ",
FUNCTION TRIM(WS-LAST)) TO WS-LINE
DISPLAY "CONCAT [" FUNCTION TRIM(WS-LINE) "]"
MOVE FUNCTION SUBSTITUTE(WS-LINE, "Ada", "Augusta Ada")
TO WS-LINE
DISPLAY "SUBST [" FUNCTION TRIM(WS-LINE) "]"
COMPUTE WS-SIZE = FUNCTION LENGTH-AN(WS-LINE)
DISPLAY "LENGTH-AN " WS-SIZE
STOP RUN.
HEX-OF 41423120
BIT-OF 01000001
CONCAT [Ada Lovelace]
SUBST [Augusta Ada Lovelace]
LENGTH-AN 0040
Compiling the same file with cobc -x -std=ibm-strict produced FUNCTION 'CONCATENATE' unknown and
FUNCTION 'SUBSTITUTE' unknown, which is the useful behaviour: the strict IBM mode is a cheap first check that a GnuCOBOL program
stays inside the Enterprise COBOL function set. One quirk was seen: in ibm-strict the GnuCOBOL list also lacks COS
(FUNCTION 'COS' unknown), although Enterprise COBOL has it, so treat that mode as a lint, not a guarantee. Dialect also
changes the list itself:
cobc setting |
Functions --list-intrinsics shows as implemented |
|---|---|
default |
103 of the 115 names that cobc knows |
|
42 |
|
77 |
|
87 |
|
73 |
|
116: every name is listed as implemented, plus the alias |
ABSOLUTE-VALUE worked as ABS under -std=ibm and -std=mf and is unknown in the default dialect. Enterprise COBOL
6.5 has no such function, so a program that compiles under -std=ibm only because of it is not portable to z/OS.
Every intrinsic function
The table lists the 82 functions of the Enterprise COBOL 6.5 Language Reference (Table 63, "Table of functions") and the
115 names that cobc --list-intrinsics prints for GnuCOBOL 3.2.0 and the manual’s Appendix C repeats, 122 distinct names
in all. They were cross-checked: the IBM documentation’s table of contents lists the same 82 function chapters, and the
GnuCOBOL manual’s Appendix C matches the cobc listing name for name. The columns mean:
-
IBM 6.5 is "Yes" when the Language Reference defines the function.
-
GnuCOBOL 3.2 is "Yes" when
cobcimplements it, and "Listed, not implemented" for the names it reserves but does not implement yet (the Programmer’s Guide says these are not yet implemented). -
Portability answers "can I rely on this in both compilers?". It has six values:
-
"Common" (68 functions): both implement it, and it is in the
-std=cobol2014word list ofcobc, which this page takes as a sign that it comes from the standard rather than from a vendor. -
"Common (vendor-specific)" (5): both implement it but the
cobol2014list does not contain it:BIT-OF,BIT-TO-CHAR,HEX-OF,HEX-TO-CHARandCONTENT-OF. -
"IBM only (vendor-specific)" (7): the Unicode functions and
UUID4. -
"GnuCOBOL only (vendor-specific)" (19) and "GnuCOBOL only (in cobol2014 list)" (11), as described above.
-
"Common name, missing in GnuCOBOL 3.2" (2):
DISPLAY-OFandNATIONAL-OF, which are in thecobol2014list and in Enterprise COBOL, but not implemented bycobc. -
"GnuCOBOL name only, not implemented" (10): only
cobcknows the name, and it does not implement it.
-
This split is a pragmatic reading of the two manuals and of the word lists of cobc, not a reading of the standard itself
(the text of ISO/IEC 1989 is not free). The cobol2014 list is not complete, either: it omits CONCATENATE and
SUBSTITUTE, which may well be standard functions.
Twelve rows are not callable in GnuCOBOL 3.2.0: cobc --list-intrinsics marks them "No" (BASECONVERT, CONVERT,
FIND-STRING, MODULE-NAME, STANDARD-COMPARE, BOOLEAN-OF-INTEGER, INTEGER-OF-BOOLEAN, CHAR-NATIONAL,
NATIONAL-OF, DISPLAY-OF, EXCEPTION-FILE-N and EXCEPTION-LOCATION-N), and the Programmer’s Guide says the ones it documents are
not yet implemented. Do not use them in portable code.
| Function | Category | What it returns | IBM 6.5 | GnuCOBOL 3.2 | Portability |
|---|---|---|---|---|---|
|
Mathematical |
Absolute value |
Yes |
Yes |
Common |
|
Mathematical |
Arccosine in radians |
Yes |
Yes |
Common |
|
Financial |
Ratio of a periodic payment to the initial amount for a given rate and number of periods |
Yes |
Yes |
Common |
|
Mathematical |
Arcsine in radians |
Yes |
Yes |
Common |
|
Mathematical |
Arctangent in radians |
Yes |
Yes |
Common |
|
Character-handling |
Convert a number between bases |
- |
Listed, not implemented |
GnuCOBOL name only, not implemented |
|
General |
Bytes of the argument as "0" and "1" characters |
Yes |
Yes |
Common (vendor-specific) |
|
Character-handling |
Characters "0" and "1" back to the bytes they describe |
Yes |
Yes |
Common (vendor-specific) |
|
General |
Integer to a boolean (bit) string |
- |
Listed, not implemented |
GnuCOBOL name only, not implemented |
|
General |
Length in bytes |
Yes |
Yes |
Common |
|
Character-handling |
Character at an ordinal position of the collating sequence |
Yes |
Yes |
Common |
|
Character-handling |
National character at an ordinal position |
- |
Listed, not implemented |
GnuCOBOL name only, not implemented |
|
Date/time |
Integer date and seconds combined in one number |
Yes |
Yes |
Common |
|
Character-handling |
Join strings (short name; not described in the Programmer’s Guide) |
- |
Yes |
GnuCOBOL only (vendor-specific) |
|
Character-handling |
Join strings |
- |
Yes |
GnuCOBOL only (vendor-specific) |
|
General |
Length of the data addressed by a pointer |
- |
Yes |
GnuCOBOL only (vendor-specific) |
|
General |
Data addressed by a pointer, for a given length |
Yes |
Yes |
Common (vendor-specific) |
|
Character-handling |
Convert a string between encodings |
- |
Listed, not implemented |
GnuCOBOL name only, not implemented |
|
Mathematical |
Cosine of an angle in radians |
Yes |
Yes |
Common |
|
General |
Currency symbol of the locale |
- |
Yes |
GnuCOBOL only (vendor-specific) |
|
Date/time |
21-character current date, time and UTC offset |
Yes |
Yes |
Common |
|
Date/time |
Integer date to YYYYMMDD |
Yes |
Yes |
Common |
|
Date/time |
Expand a windowed YYMMDD to YYYYMMDD |
Yes |
Yes |
Common |
|
Date/time |
Integer date to Julian YYYYDDD |
Yes |
Yes |
Common |
|
Date/time |
Expand a windowed YYDDD to YYYYDDD |
Yes |
Yes |
Common |
|
Character-handling |
National or UTF-8 data to alphanumeric in a code page |
Yes |
Listed, not implemented |
Common name, missing in GnuCOBOL 3.2 |
|
Mathematical |
Approximation of e |
Yes |
Yes |
Common |
|
General |
File status and file name of the last failing I/O statement |
- |
Yes |
GnuCOBOL only (in cobol2014 list) |
|
General |
National-character form of EXCEPTION-FILE |
- |
Listed, not implemented |
GnuCOBOL name only, not implemented |
|
General |
Program, paragraph and line of the last exception |
- |
Yes |
GnuCOBOL only (in cobol2014 list) |
|
General |
National-character form of EXCEPTION-LOCATION |
- |
Listed, not implemented |
GnuCOBOL name only, not implemented |
|
General |
Statement that raised the last exception |
- |
Yes |
GnuCOBOL only (in cobol2014 list) |
|
General |
Name of the last exception condition |
- |
Yes |
GnuCOBOL only (in cobol2014 list) |
|
Mathematical |
e raised to a power |
Yes |
Yes |
Common |
|
Mathematical |
10 raised to a power |
Yes |
Yes |
Common |
|
Mathematical |
Factorial of a non-negative integer |
Yes |
Yes |
Common |
|
Character-handling |
Find a string within a string |
- |
Listed, not implemented |
GnuCOBOL name only, not implemented |
|
Date/time |
Current date and time in a given format |
Yes |
Yes |
Common |
|
Date/time |
Integer date in a given format |
Yes |
Yes |
Common |
|
Date/time |
Integer date and time in a given format |
Yes |
Yes |
Common |
|
Date/time |
Time in a given format |
Yes |
Yes |
Common |
|
Mathematical |
Digits to the right of the decimal point |
- |
Yes |
GnuCOBOL only (in cobol2014 list) |
|
General |
Bytes of the argument as hexadecimal characters |
Yes |
Yes |
Common (vendor-specific) |
|
Character-handling |
Hexadecimal digit characters back to the bytes they describe |
Yes |
Yes |
Common (vendor-specific) |
|
General |
Largest value a numeric item can hold |
- |
Yes |
GnuCOBOL only (in cobol2014 list) |
|
Mathematical |
Greatest integer not greater than the argument (rounds down) |
Yes |
Yes |
Common |
|
General |
Boolean (bit) string to an integer |
- |
Listed, not implemented |
GnuCOBOL name only, not implemented |
|
Date/time |
YYYYMMDD to integer date |
Yes |
Yes |
Common |
|
Date/time |
Julian YYYYDDD to integer date |
Yes |
Yes |
Common |
|
Date/time |
Formatted date string to integer date |
Yes |
Yes |
Common |
|
Mathematical |
Integer part of the argument (truncates toward zero) |
Yes |
Yes |
Common |
|
General |
Length in characters (national positions for NATIONAL data) |
Yes |
Yes |
Common |
|
General |
Length in bytes (same as BYTE-LENGTH) |
- |
Yes |
GnuCOBOL only (vendor-specific) |
|
General |
Compare two strings with a locale collation |
- |
Yes |
GnuCOBOL only (in cobol2014 list) |
|
Date/time |
YYYYMMDD in the current locale format |
- |
Yes |
GnuCOBOL only (in cobol2014 list) |
|
Date/time |
hhmm or hhmmss in the current locale format |
- |
Yes |
GnuCOBOL only (in cobol2014 list) |
|
Date/time |
Seconds past midnight in the current locale format |
- |
Yes |
GnuCOBOL only (in cobol2014 list) |
|
Mathematical |
Natural logarithm |
Yes |
Yes |
Common |
|
Mathematical |
Base-10 logarithm |
Yes |
Yes |
Common |
|
Character-handling |
Letters to lower case |
Yes |
Yes |
Common |
|
General |
Smallest value a numeric item can hold |
- |
Yes |
GnuCOBOL only (in cobol2014 list) |
|
Statistical |
Largest argument |
Yes |
Yes |
Common |
|
Statistical |
Arithmetic mean of the arguments |
Yes |
Yes |
Common |
|
Statistical |
Median of the arguments |
Yes |
Yes |
Common |
|
Statistical |
Mean of the smallest and largest arguments |
Yes |
Yes |
Common |
|
Statistical |
Smallest argument |
Yes |
Yes |
Common |
|
Mathematical |
Integer modulo; the result takes the sign of the divisor |
Yes |
Yes |
Common |
|
General |
Entry-point name of the caller |
- |
Yes |
GnuCOBOL only (vendor-specific) |
|
Date/time |
Compilation date of the running program, YYYYMMDD |
- |
Yes |
GnuCOBOL only (vendor-specific) |
|
Date/time |
Compilation date and time of the running program, formatted |
- |
Yes |
GnuCOBOL only (vendor-specific) |
|
General |
Program-ID of the running program |
- |
Yes |
GnuCOBOL only (vendor-specific) |
|
General |
Name of the running module (a standard function) |
- |
Listed, not implemented |
GnuCOBOL name only, not implemented |
|
General |
Path of the executable |
- |
Yes |
GnuCOBOL only (vendor-specific) |
|
General |
Source file name given to cobc |
- |
Yes |
GnuCOBOL only (vendor-specific) |
|
Date/time |
Compilation time of the running program, hhmmss |
- |
Yes |
GnuCOBOL only (vendor-specific) |
|
General |
Monetary decimal point of the locale |
- |
Yes |
GnuCOBOL only (vendor-specific) |
|
General |
Monetary thousands separator of the locale |
- |
Yes |
GnuCOBOL only (vendor-specific) |
|
Character-handling |
Alphanumeric data to national characters |
Yes |
Listed, not implemented |
Common name, missing in GnuCOBOL 3.2 |
|
General |
Numeric decimal point of the locale |
- |
Yes |
GnuCOBOL only (vendor-specific) |
|
General |
Numeric thousands separator of the locale |
- |
Yes |
GnuCOBOL only (vendor-specific) |
|
General |
Simple numeric text (sign, CR/DB) to a number |
Yes |
Yes |
Common |
|
General |
Numeric text with currency sign and separators to a number |
Yes |
Yes |
Common |
|
General |
Floating-point text (with an exponent) to a number |
Yes |
Yes |
Common |
|
Character-handling |
Ordinal position of a character in the collating sequence |
Yes |
Yes |
Common |
|
Statistical |
Position (1, 2, …) of the largest argument |
Yes |
Yes |
Common |
|
Statistical |
Position (1, 2, …) of the smallest argument |
Yes |
Yes |
Common |
|
Mathematical |
Approximation of pi |
Yes |
Yes |
Common |
|
Financial |
Present value of a series of period-end amounts at a discount rate |
Yes |
Yes |
Common |
|
Mathematical |
Pseudo-random number between 0 and 1, optional seed |
Yes |
Yes |
Common |
|
Statistical |
Largest minus smallest argument |
Yes |
Yes |
Common |
|
Mathematical |
Remainder; the result takes the sign of the dividend |
Yes |
Yes |
Common |
|
Character-handling |
Characters in reverse order |
Yes |
Yes |
Common |
|
Date/time |
Formatted time string to seconds |
Yes |
Yes |
Common |
|
Date/time |
Seconds since midnight |
Yes |
Yes |
Common |
|
Mathematical |
+1, 0 or -1 according to the sign |
Yes |
Yes |
Common |
|
Mathematical |
Sine of an angle in radians |
Yes |
Yes |
Common |
|
Mathematical |
Square root |
Yes |
Yes |
Common |
|
General |
Compare two strings with a standard cultural ordering |
- |
Listed, not implemented |
GnuCOBOL name only, not implemented |
|
Statistical |
Standard deviation of the arguments |
Yes |
Yes |
Common |
|
General |
Length in bytes without trailing spaces |
- |
Yes |
GnuCOBOL only (vendor-specific) |
|
Character-handling |
Replace each from-string by its to-string |
- |
Yes |
GnuCOBOL only (vendor-specific) |
|
Character-handling |
SUBSTITUTE ignoring case when matching |
- |
Yes |
GnuCOBOL only (vendor-specific) |
|
Statistical |
Sum of the arguments |
Yes |
Yes |
Common |
|
Mathematical |
Tangent of an angle in radians |
Yes |
Yes |
Common |
|
Date/time |
0 if a valid YYYYMMDD, else the field in error |
Yes |
Yes |
Common |
|
Date/time |
0 if a valid YYYYDDD, else the field in error |
Yes |
Yes |
Common |
|
Date/time |
0 if a string matches its date/time format, else the error position |
Yes |
Yes |
Common |
|
General |
0 if the text is valid for NUMVAL, else the error position |
Yes |
Yes |
Common |
|
General |
0 if the text is valid for NUMVAL-C, else the error position |
Yes |
Yes |
Common |
|
General |
0 if the text is valid for NUMVAL-F, else the error position |
Yes |
Yes |
Common |
|
Character-handling |
Remove leading and/or trailing spaces |
Yes |
Yes |
Common |
|
Character-handling |
Length in UTF-8 or UTF-16 characters |
Yes |
- |
IBM only (vendor-specific) |
|
Character-handling |
Byte position of the nth UTF-8 or UTF-16 character |
Yes |
- |
IBM only (vendor-specific) |
|
Character-handling |
Letters to upper case |
Yes |
Yes |
Common |
|
Character-handling |
Substring counted in UTF-8 or UTF-16 characters |
Yes |
- |
IBM only (vendor-specific) |
|
Character-handling |
Position of the first Unicode supplementary character |
Yes |
- |
IBM only (vendor-specific) |
|
General |
36-character version 4 UUID |
Yes |
- |
IBM only (vendor-specific) |
|
Character-handling |
0 if valid Unicode data, else the first invalid position |
Yes |
- |
IBM only (vendor-specific) |
|
Character-handling |
Width in bytes of the nth UTF-8 or UTF-16 character |
Yes |
- |
IBM only (vendor-specific) |
|
Statistical |
Variance of the arguments |
Yes |
Yes |
Common |
|
Date/time |
Date and time the program was compiled |
Yes |
Yes |
Common |
|
Date/time |
Expand a windowed two-digit year to four digits |
Yes |
Yes |
Common |
Pitfalls
Each program here is deliberately wrong. The messages are the real output of cobc -x -Wall (GnuCOBOL 3.2.0).
ALL subscripts. The IBM form FUNCTION SUM(WS-LOANS(ALL)) is not accepted:
IDENTIFICATION DIVISION.
PROGRAM-ID. BADALL.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-WEEK.
05 WS-LOANS PIC 9(3) OCCURS 7 TIMES.
01 WS-TOTAL PIC 9(4).
PROCEDURE DIVISION.
COMPUTE WS-TOTAL = FUNCTION SUM(WS-LOANS(ALL))
STOP RUN.
bad-all.cob:9: error: syntax error, unexpected ALL
7 | 01 WS-TOTAL PIC 9(4).
8 | PROCEDURE DIVISION.
9 > COMPUTE WS-TOTAL = FUNCTION SUM(WS-LOANS(ALL))
10 | STOP RUN.
11 | <EOF>
A parenthesised expression after a data name. The Language Reference writes a call such as FUNCTION Sum(a b (c / d))
with an expression in the last place. GnuCOBOL 3.2.0 reads b (c / d) as a subscripted b:
IDENTIFICATION DIVISION.
PROGRAM-ID. BADPAREN.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-A PIC 99 VALUE 5.
01 WS-B PIC 99 VALUE 6.
01 WS-C PIC 99 VALUE 8.
01 WS-D PIC 99 VALUE 2.
01 WS-TOTAL PIC 999.
PROCEDURE DIVISION.
COMPUTE WS-TOTAL = FUNCTION SUM(WS-A WS-B (WS-C / WS-D))
STOP RUN.
bad-paren.cob:11: error: 'WS-B' cannot be subscripted
9 | 01 WS-TOTAL PIC 999.
10 | PROCEDURE DIVISION.
11 > COMPUTE WS-TOTAL = FUNCTION SUM(WS-A WS-B (WS-C / WS-D))
12 | STOP RUN.
13 | <EOF>
Putting the expression first, as syntax.cob does, or writing it as a COMPUTE of its own avoids the problem. A comma
helps only when the next argument is on the same line: with the comma at the end of a line and the parenthesis at the
start of the next, the same error appeared. Both forms are valid Enterprise COBOL, so this is a GnuCOBOL limitation.
A function as a receiving item. A function value is not storage:
IDENTIFICATION DIVISION.
PROGRAM-ID. BADRECV.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-TITLE PIC X(30).
PROCEDURE DIVISION.
MOVE "COBOL" TO FUNCTION UPPER-CASE(WS-TITLE)
STOP RUN.
bad-receive.cob:7: error: syntax error, unexpected FUNCTION UPPER-CASE
5 | 01 WS-TITLE PIC X(30).
6 | PROCEDURE DIVISION.
7 > MOVE "COBOL" TO FUNCTION UPPER-CASE(WS-TITLE)
8 | STOP RUN.
9 | <EOF>
A function the compiler does not have. The Unicode functions and UUID4 are Enterprise COBOL only:
IDENTIFICATION DIVISION.
PROGRAM-ID. BADUNK.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-TEXT PIC X(30) VALUE "Circulation".
01 WS-SIZE PIC 9(4).
PROCEDURE DIVISION.
COMPUTE WS-SIZE = FUNCTION ULENGTH(WS-TEXT)
DISPLAY FUNCTION UUID4
STOP RUN.
bad-unknown.cob:8: error: FUNCTION 'ULENGTH' unknown
6 | 01 WS-SIZE PIC 9(4).
7 | PROCEDURE DIVISION.
8 > COMPUTE WS-SIZE = FUNCTION ULENGTH(WS-TEXT)
9 | DISPLAY FUNCTION UUID4
10 | STOP RUN.
bad-unknown.cob:9: error: FUNCTION 'UUID4' unknown
7 | PROCEDURE DIVISION.
8 | COMPUTE WS-SIZE = FUNCTION ULENGTH(WS-TEXT)
9 > DISPLAY FUNCTION UUID4
10 | STOP RUN.
11 | <EOF>
A data name that is also a function name, under REPOSITORY. With FUNCTION ALL INTRINSIC in force, the earlier
SQRT data item no longer compiles:
IDENTIFICATION DIVISION.
PROGRAM-ID. BADNAMES.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
FUNCTION ALL INTRINSIC.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 SQRT PIC 99 VALUE 0.
PROCEDURE DIVISION.
MAIN-PARA.
MOVE 4 TO SQRT
DISPLAY SQRT
STOP RUN.
bad-names.cob: in paragraph 'MAIN-PARA':
bad-names.cob:12: error: syntax error, unexpected intrinsic function name
10 | PROCEDURE DIVISION.
11 | MAIN-PARA.
12 > MOVE 4 TO SQRT
13 | DISPLAY SQRT
14 | STOP RUN.
bad-names.cob:13: error: FUNCTION 'SQRT' has wrong number of arguments
11 | MAIN-PARA.
12 | MOVE 4 TO SQRT
13 > DISPLAY SQRT
14 | STOP RUN.
15 | <EOF>
Where the book is outdated
Tom Taulli’s Modern Mainframe Development introduces NUMVAL, NUMVAL-C and the case-conversion functions in its
chapters on arithmetic and on tables and strings, and it takes Enterprise COBOL V6.3 as the latest release. This page
uses 6.5. According to IBM’s "What’s new" pages, UUID4 already arrived in 6.3, CONTENT-OF in 6.4, and 6.5 added UTF-8
arguments to ULENGTH, so the function set of a current compiler is larger than the one a 6.3 reader has seen. The
book also cannot tell you that GnuCOBOL 3.2 has BIT-OF and HEX-OF, or that the standard has been revised in 2014 and
2023. Check the "What’s new" page of the Enterprise COBOL documentation for the release that introduced a function before
relying on it in a shop that runs an older compiler.