Counts the number of elements on the operand stack and pushes this count onto the stack.

1. Description

The count operator returns the current depth of the operand stack as an integer. This is useful for stack management, debugging, and implementing stack-aware operations.

After execution, the stack contains one more element than before (the count itself), so the count value reflects the stack depth before count was executed.

This is a Level 1 operator, available in all PostScript implementations.

2. Syntax

any1 ... anyn count any1 ... anyn n

2.1. Stack Effect

Table 1. Before Execution
Position Content

Top to Bottom

any1 …​ anyn - Any number of elements (possibly zero)

Table 2. After Execution
Position Content

Top

n (integer) - Number of elements that were on stack

Top-1 to Top-n

any1 …​ anyn - Original elements (unchanged)

3. Parameters

None. count takes no operands from the stack.

4. Return Values

Returns a non-negative integer representing the number of elements that were on the stack before count was executed.

5. Examples

5.1. Basic Usage

% Empty stack
clear count         % Stack: 0

% Stack with elements
clear 1 2 3 count   % Stack: 1 2 3 3

% After count, stack has one more element
clear 1 2 count     % Stack: 1 2 2
count               % Stack: 1 2 2 3

5.2. Checking Stack Depth

% Verify sufficient elements before operation
count 3 ge {
    % At least 3 elements, safe to proceed
    3 array astore pop
} {
    (Insufficient elements on stack) print
} ifelse

5.3. Stack Debugging

% Print current stack depth
/showDepth {
    count (Stack depth: ) print =
} def

clear
showDepth           % Prints: Stack depth: 0
1 2 3
showDepth           % Prints: Stack depth: 3

5.4. Preserving Stack State

% Save stack depth before operation
count               % Remember initial depth
% ... perform operations that may change stack ...
count exch sub      % Calculate elements added/removed

6. Advanced Examples

6.1. Implementing cleartomark Safely

% Count elements before finding mark
/safeCountToMark {
    count mark exch
    % Find mark position
    0 1 2 index 1 sub {
        index type /marktype eq {
            exch pop exit
        } {
            pop
        } ifelse
    } for
} def

6.2. Stack Depth Assertions

% Assert exact stack depth
/assertDepth {      % ... expected -> ... (or error)
    count 1 sub     % Get actual depth (excluding expected)
    1 index ne {
        (Stack depth mismatch!) print
        count =
    } {
        pop
    } ifelse
} def

% Usage
clear 1 2 3
3 assertDepth       % OK
4 assertDepth       % Prints error

6.3. Clearing to Specific Depth

% Pop elements until stack has desired depth
/popToDepth {       % ... targetDepth -> ...
    {
        count 1 index le {
            pop exit
        } {
            exch pop
        } ifelse
    } loop
} def

1 2 3 4 5 6 7 8 9 10
3 popToDepth        % Stack: 1 2 3

6.4. Stack Monitoring

% Monitor stack growth during procedure
/monitorStack {     % proc -> result (with stack report)
    count exch      % initial_count proc
    exec            % Execute procedure
    count           % final_count
    (Stack grew by: ) print
    exch sub =
} def

% Usage
{ 1 2 3 } monitorStack      % Prints: Stack grew by: 3

7. Edge Cases and Common Pitfalls

Remember that count itself adds one element to the stack, so count after count increases by 1 each time.

7.1. Count Adds to Stack

% CAUTION: count modifies the stack
clear
count               % Stack: 0
count               % Stack: 0 1 (not 0 0!)
count               % Stack: 0 1 2

7.2. Using Count in Conditionals

% GOOD: Use count result immediately
count 0 eq {
    (Stack is empty) print
} if

% BAD: Don't save count then test
count /depth exch def
depth 0 eq {        % depth value is stale if stack changed!
    (May not be empty) print
} if

7.3. Count Includes All Elements

% Count includes marks and all other elements
clear
mark 1 2 3
count               % Stack: mark 1 2 3 4
% All 4 elements counted (including mark)
Use count immediately before the operation that needs to know stack depth. Don’t store the count value for later use, as the stack may change.
  • counttomark - Count elements until a mark

  • clear - Remove all elements from stack

  • pop - Remove single element

  • copy - Copy n elements

  • roll - Rotate n elements

9. PostScript Level

Available in: PostScript Level 1 and higher

This is a fundamental operator available in all PostScript implementations.

10. Error Conditions

stackoverflow

The stack is at maximum capacity and cannot accommodate the count value. This is extremely rare in practice.

% (Only possible if stack nearly full)

11. Performance Considerations

The count operator is extremely fast with O(1) constant time complexity. The interpreter maintains a running count of stack elements, so this operation doesn’t need to traverse the stack.

Use count freely for debugging and stack management without performance concerns.

12. Best Practices

  1. Use for safety checks: Always verify stack depth before operations that require specific numbers of elements

  2. Immediate use: Use the count value immediately; don’t store it for later

  3. Debugging aid: Excellent for understanding stack behavior during development

  4. Combine with copy: Use count to determine how many elements to copy

  5. Document assumptions: When procedures assume certain stack depths, document and verify with count

12.1. Safe Procedure Patterns

% Check prerequisites before operation
/safeOperation {    % a b c -> result
    % Require exactly 3 arguments
    count 3 lt {
        (Error: safeOperation requires 3 arguments) print
        quit
    } if

    % Perform operation knowing we have enough elements
    add add
} def

% Usage
1 2 safeOperation       % Prints error
1 2 3 safeOperation     % Returns 6

12.2. Stack State Verification

% Verify procedure maintains stack balance
/testStackBalance {  % proc -> (reports balance)
    count           % Save initial depth
    exch exec       % Execute procedure
    count           % Get final depth
    exch sub        % Calculate difference
    dup 0 ne {
        (Warning: stack imbalance: ) print =
    } {
        pop
        (Stack balanced) print
    } ifelse
} def

13. See Also


Back to top

Copyright © 2025 Ribose. PostScript is a trademark of Adobe. Distributed under the MIT License.