4.3Bloom · AnNot started

Restricted ABAP — the forbidden list

Reading depth

What you'll learn

In a Cloud Development package, classic statements like WRITE, CALL TRANSACTION, CALL SCREEN, CALL FUNCTION DESTINATION, macros, EXEC SQL and IMPORT/EXPORT FROM MEMORY are syntax errors — ATC variant ABAP_CLOUD_DEVELOPMENT_DEFAULT is the source of truth.

  • These are syntax errors, not warnings: WRITE/LIST-PROCESSING, CALL TRANSACTION/SUBMIT/LEAVE TO TRANSACTION.
  • Also forbidden: CALL SCREEN/SET SCREEN/CALL DIALOG, CALL FUNCTION ... DESTINATION, and macros.
  • Native SQL (EXEC SQL), held cursors, and IMPORT/EXPORT FROM MEMORY or SHARED BUFFER are out too.

Inside an ABAP-for-Cloud-Development package the compiler refuses a long list of classic statements outright — they are syntax errors, not warnings. The categories worth memorising are: list processing and screen output (`write ... /`, `new-page`, `list-processing`); program and transaction control (`call transaction`, `submit`, `leave to transaction`); classic dialog UI (`call screen`, `set screen`, `call dialog`); destination-based remote calls (`call function ... destination`); and macros (`define` / `end-of-definition`).

It continues with the data-tunnelling and native escapes: native SQL (`exec sql`) and held cursors (`open cursor ... with hold`); and any transfer through ABAP or shared memory — `import from memory` / `export to memory`, and `import/export from shared buffer`, plus the shared-memory-objects framework. Authority checks against non-released objects are out too; you use the released authorization API instead. The common thread is that every one of these either renders to a GUI, jumps out of the controlled stack, or reaches data behind SAP's back — all incompatible with an upgrade-stable contract.

The full forbidden set ships with the kernel (inspectable via `cl_abap_restriction_descr_factory`), but in day-to-day work the ATC check variant `ABAP_CLOUD_DEVELOPMENT_DEFAULT` is the practical source of truth: it is what gates your transports and your pipeline, and it grows stricter with each release, so a package that is clean today can surface new findings after an FPS.

Key points

  • These are syntax errors, not warnings: WRITE/LIST-PROCESSING, CALL TRANSACTION/SUBMIT/LEAVE TO TRANSACTION.
  • Also forbidden: CALL SCREEN/SET SCREEN/CALL DIALOG, CALL FUNCTION ... DESTINATION, and macros.
  • Native SQL (EXEC SQL), held cursors, and IMPORT/EXPORT FROM MEMORY or SHARED BUFFER are out too.
  • ATC variant ABAP_CLOUD_DEVELOPMENT_DEFAULT is the practical source of truth for what is allowed.
  • The variant gains checks each release — a green pipeline today can red after an FPS.

Examples

BeforeA classic control-flow snippet

Valid Standard ABAP, every line a syntax error in a Cloud Development package: list output, a transaction launch, a memory tunnel, and a macro.

ABAPwrite: / 'Posting order'.
call transaction 'va01'.
export lt_buffer to memory id 'ZORD'.
define add_one.
  &1 = &1 + 1.
end-of-definition.
AfterThe Cloud-clean shape

Output goes through a released log API; navigation moves to Fiori + released services; state passes as typed method parameters; the macro becomes a normal method call.

ABAPdata(log) = cl_bali_log=>create( ).
" hand data on as typed parameters, not via memory
data(result) = me->process_order( lt_orders ).
" no macros: add_one becomes a real method
data(next) = me->increment( current ).

Source notes: clean-core-curriculum §4.3

Ask Claude

Build a prompt from this lesson + your question and open a fresh Claude chat with it pre-filled — handy for adapting a before/after pattern to your own object.

Code exercise · ABAP

Macros (DEFINE ... END-OF-DEFINITION) are on the forbidden list for ABAP for Cloud Development — abaplint flags the DEFINE. Replace the macro with plain inline ABAP so the method reads straight through, then re-check until it's clean.

The starter trips abaplint rule avoid_use. Fix the code until the check is clean.

Hint

Delete the DEFINE/END-OF-DEFINITION block and its call, and write the one line it expanded to directly: rv_x = iv_x + 1.