Compound literal adalah fitur C99 yang memungkinkan kita membuat objek anonim bertipe array atau struct langsung di ekspresi, tanpa harus mendeklarasikan variabel terlebih dahulu. Sintaksnya adalah (type){init}, misalnya (int[]){1, 2, 3} membuat array anonim tiga elemen, atau (struct Point){.x=1, .y=2} membuat struct anonim. Fitur ini sangat berguna untuk mengoper nilai sementara ke fungsi yang menerima pointer, mendefinisikan konstanta default inline, dan membangun array of pointer tanpa variabel perantara. Pada chapter ini kita akan mengeksplorasi berbagai pola pemakaian compound literal.
Membuat Array dan Struct Anonim #
Tanpa compound literal, kita harus mendeklarasikan variabel sementara setiap kali ingin mengoper array ke fungsi. Dengan compound literal, ekspresi bisa ditulis inline dalam satu baris.
#include <stdio.h>
int main(void) {
/* Compound literal: array anonim int[3] */
int *p = (int[]){1, 2, 3};
printf("array anonim: %d %d %d\n", p[0], p[1], p[2]);
/* Compound literal: struct anonim */
struct Point { int x, y; };
struct Point *pt = &(struct Point){.x = 10, .y = 20};
printf("point: (%d, %d)\n", pt->x, pt->y);
/* Compound literal sebagai argumen fungsi */
int sum3(const int *arr) {
return arr[0] + arr[1] + arr[2];
}
printf("sum3 = %d\n", sum3((int[]){4, 5, 6}));
/* Compound literal const: bisa disimpan di read-only memory */
const int *c = (const int[]){10, 20, 30, 40};
printf("konstan: %d %d %d %d\n", c[0], c[1], c[2], c[3]);
return 0;
}Output yang Dihasilkan:
array anonim: 1 2 3
point: (10, 20)
sum3 = 15
konstan: 10 20 30 40Mari kita telaah baris-baris kode di atas:
- Baris 6 (
int *p = (int[]){1, 2, 3};): compound literal bertipeint[3]. Ekspresi ini membuat array anonim di memori dan mengembalikan pointer ke elemen pertamanya. Pointerplalu bisa dipakai seperti array biasa. - Baris 10 (
struct Point *pt = &(struct Point){.x = 10, .y = 20};): compound literal untuk struct. Kita mengambil alamat dengan&sehinggaptmenjadi pointer ke struct anonim. - Baris 15 (
sum3((int[]){4, 5, 6})): argumen fungsi langsung berupa compound literal. Tidak perlu variabel perantara. - Baris 19 (
const int *c = (const int[]){10, 20, 30, 40};): kualifikasiconstpada compound literal memungkinkan compiler menempatkan objek di read-only memory (segment.rodata), sama seperti string literal. - Baris 21-23: akses elemen seperti array biasa. Compound literal tidak “hilang” setelah statement—lifetime-nya mengikuti scope di mana dideklarasikan.
Compound Literal untuk Default Config dan Array of Pointer #
Compound literal sangat berguna untuk membuat konfigurasi default atau membangun array pointer ke struct sementara tanpa harus menamai setiap struct.
#include <stdio.h>
/* Fungsi yang menerima array (decay ke pointer) */
static void cetak_arr(const int *arr, int n) {
printf("[");
for (int i = 0; i < n; i++) {
if (i) printf(", ");
printf("%d", arr[i]);
}
printf("]\n");
}
int main(void) {
/* Pakai compound literal langsung sebagai argumen */
cetak_arr((int[]){7, 14, 21}, 3);
cetak_arr((int[]){100, 200, 300, 400}, 4);
/* Compound literal untuk default config */
typedef struct {
const char *host;
int port;
int timeout;
} Config;
const Config *cfg = &(const Config){
.host = "localhost",
.port = 8080,
.timeout = 30
};
printf("config: %s:%d timeout=%d\n", cfg->host, cfg->port, cfg->timeout);
/* Compound literal sebagai elemen array */
typedef struct { int r, g, b; } RGB;
const RGB *palet[] = {
&(RGB){255, 0, 0},
&(RGB){0, 255, 0},
&(RGB){0, 0, 255},
};
for (int i = 0; i < 3; i++) {
printf("warna[%d] = #%02X%02X%02X\n",
i, palet[i]->r, palet[i]->g, palet[i]->b);
}
return 0;
}Output yang Dihasilkan:
[7, 14, 21]
[100, 200, 300, 400]
config: localhost:8080 timeout=30
warna[0] = #FF0000
warna[1] = #00FF00
warna[2] = #0000FFTanpa compound literal, contoh di atas membutuhkan tiga deklarasi struct RGB terpisah untuk warna merah, hijau, dan biru. Compound literal memungkinkan kita menuliskan ketiga struct tersebut langsung di dalam initializer array, membuat kode lebih ringkas dan deklarasi warna berdekatan dengan penggunaannya.
Compound Literal vs Variabel Bernama #
Kapan memakai compound literal, kapan memakai variabel bernama? Aturan umum:
- Pakai compound literal bila: objek dipakai sekali di satu tempat, ukurannya kecil, dan tidak perlu di-debug dengan nama.
- Pakai variabel bernama bila: objek dipakai beberapa kali, perlu nama deskriptif, atau menjadi bagian dari logika kompleks yang ingin di-debug.
Compound literal sering dipakai di test suite untuk membangun input data, di driver kode untuk konfigurasi default, dan di binding API asing yang membutuhkan struct tag sementara.