Di dalam switch, statement break berperan sebagai “pintu keluar”. Tanpa break, eksekusi tidak berhenti di akhir sebuah case—eksekusi justru jatuh ke case berikutnya dan terus mengeksekusi statement-statement di sana. Perilaku ini disebut fallthrough. Pada chapter ini kita akan membedah kapan break wajib dipakai, kapan fallthrough sengaja dimanfaatkan, serta bagaimana komentar /* fall through */ dipakai untuk menenangkan peringatan -Wimplicit-fallthrough dari compiler modern.

break Wajib di Akhir Setiap Case #

Pada pemakaian switch yang umum, setiap case mengeksekusi statement-statementnya lalu break keluar dari blok switch. Tanpa break, eksekusi terus jatuh ke case berikutnya walaupun case tersebut tidak cocok dengan nilai ekspresi. Perilaku ini sering kali tidak diinginkan—dan justru menjadi salah satu bug paling sering di kode C pemula.

c
#include <stdio.h>

int main(void) {
    int level = 2;

    switch (level) {
        case 1:
            printf("Akses dasar\n");
            break;
        case 2:
            printf("Akses standar\n");
            /* TANPA break - akan jatuh ke case 3 */
        case 3:
            printf("Akses premium\n");
            break;
        default:
            printf("Tidak ada akses\n");
            break;
    }
    return 0;
}

Output compiler (dengan peringatan -Wimplicit-fallthrough):

text
test_bf1.c: In function 'main':
test_bf1.c:11:13: warning: this statement may fall through [-Wimplicit-fallthrough=]
   11 |             printf("Akses standar\n");
      |             ^~~~~~~~~~~~~~~~~~~~~~~~~
test_bf1.c:13:9: note: here
   13 |         case 3:
      |         ^~~~

Output yang Dihasilkan (saat dijalankan):

text
Akses standar
Akses premium

Mari kita telaah apa yang terjadi:

  1. Baris 5 (int level = 2;): variabel level diisi 2.
  2. Baris 9 (case 2:): compiler melompat ke label case 2:, mengeksekusi printf("Akses standar\n");.
  3. Baris 11 (tanpa break;): karena tidak ada break, eksekusi jatuh ke statement di case berikutnya tanpa memeriksa apakah level == 3.
  4. Baris 12 (case 3:): label ini dilewati sebagai label, statement printf("Akses premium\n"); tetap dieksekusi karena eksekusi sedang mengalir menurun.
  5. Baris 14 (break;): akhirnya break menghentikan eksekusi switch.

Fallthrough Sengaja dengan /* fall through */ #

Terkadang fallthrough memang diinginkan. Misalnya, ketika beberapa case sengaja berbagi statement akhir, atau ketika logika bersifat kumulatif (case 3 menjalankan statement-nya lalu lanjut menjalankan statement case 2 dan case 1). Untuk menandai bahwa fallthrough memang disengaja, kita menambahkan komentar /* fall through */ di antara dua case. Compiler GCC mengenali komentar ini dan tidak memunculkan peringatan -Wimplicit-fallthrough.

c
#include <stdio.h>

int main(void) {
    int level = 2;

    switch (level) {
        case 1:
            printf("Akses dasar\n");
            break;
        case 2:
            printf("Akses standar\n");
            /* fall through */
        case 3:
            printf("Akses premium\n");
            break;
        default:
            printf("Tidak ada akses\n");
            break;
    }
    return 0;
}

Output yang Dihasilkan:

text
Akses standar
Akses premium

Pada contoh di atas, output program sama persis dengan versi tanpa komentar—tetapi compiler tidak lagi memunculkan peringatan -Wimplicit-fallthrough. Komentar /* fall through */ menjadi dokumentasi eksplisit bahwa fallthrough adalah perilaku yang sengaja diinginkan.

Pola Kalkulator dengan break #

Pola paling lazim switch adalah menu operasi: setiap case mengeksekusi satu operasi berbeda lalu break keluar. Berikut kalkulator sederhana yang memilih operasi berdasarkan karakter operator.

c
#include <stdio.h>

int main(void) {
    /* Kalkulator sederhana memakai break untuk memilih satu cabang */
    int a = 10, b = 5, hasil = 0;
    char op = '+';

    switch (op) {
        case '+':
            hasil = a + b;
            break;
        case '-':
            hasil = a - b;
            break;
        case '*':
            hasil = a * b;
            break;
        case '/':
            if (b != 0) {
                hasil = a / b;
            } else {
                printf("Error: pembagian nol\n");
            }
            break;
        default:
            printf("Operator tidak dikenal\n");
            break;
    }
    printf("hasil = %d\n", hasil);

    /* Fallthrough sengaja: hitung hari libur kumulatif */
    int hari_libur = 3;   /* 1=libur nasional, 2=cuti, 3=weekend */
    int total_libur = 0;
    switch (hari_libur) {
        case 3:
            total_libur += 1;   /* weekend: 1 hari */
            /* fall through */
        case 2:
            total_libur += 2;   /* cuti: 2 hari */
            /* fall through */
        case 1:
            total_libur += 1;   /* libur nasional: 1 hari */
            break;
        default:
            total_libur = 0;
            break;
    }
    printf("total_libur = %d\n", total_libur);
    return 0;
}

Output yang Dihasilkan:

text
hasil = 15
total_libur = 4

Pada blok pertama (switch (op)), setiap case menghitung hasil lalu break keluar. Karena op = '+', hanya case '+' yang dieksekusi: hasil = 10 + 5 = 15.

Pada blok kedua (switch (hari_libur)), hari_libur = 3. Compiler melompat ke case 3:, menambah total_libur += 1 (menjadi 1), lalu jatuh ke case 2: menambah 2 (menjadi 3), lalu jatuh ke case 1: menambah 1 (menjadi 4), baru break keluar. Pola fallthrough kumulatif ini berguna saat logika bertingkat: anggap seseorang yang mengambil libur weekend (1 hari) otomatis juga mengambil cuti (2 hari) dan libur nasional (1 hari) sehingga total 4 hari.

Aturan Praktis break dan Fallthrough #

Beberapa aturan praktis untuk menulis switch yang aman dan jelas:

  1. Default: selalu break di akhir setiap case, kecuali ada alasan kuat untuk fallthrough.
  2. Tandai fallthrough sengaja dengan komentar /* fall through */ agar compiler tidak memunculkan peringatan dan agar pembaca kode lain tahu perilaku itu disengaja.
  3. Letakkan default di akhir dan tetap sertakan break di sana—meskipun secara teknis break setelah default opsional bila default adalah case terakhir, hal ini melindungi dari bug saat ada case baru ditambahkan di bawahnya.
  4. case kosong (beberapa label berurutan tanpa statement) tidak membutuhkan /* fall through */ karena tidak ada statement yang dapat “jatuh”—ini hanyalah rangkaian label menuju statement pertama yang ada.

Pada chapter berikutnya kita akan beralih ke bentuk percabangan lain: operator conditional ? :—konstruksi ekspresi (bukan statement) yang sering menjadi alternatif ringkas untuk if-else sederhana.