C17 (ISO/IEC 9899:2018, kadang disebut C18 berdasarkan tahun publikasi ISO) adalah standar C yang paling singkat fungsinya: tidak menambahkan satu fitur bahasa baru pun. C17 dirilis semata-mata untuk mengumpulkan defect report (DR) yang dikumpulkan komite WG14 sejak C11—klarifikasi wording, perbaikan definisi memory model, dan obsolete marking untuk fitur yang segera dihapus di C23. Bab ini memperlihatkan bagaimana kode C11 yang sama dapat dikompilasi dengan -std=c17 tanpa perubahan apa pun, lalu menunjukkan beberapa macro penting yang menjadi baseline portabilitas modern: __STDC_VERSION__ = 201710L, __STDC_NO_ATOMICS, __STDC_NO_THREADS, dan status ATOMIC_VAR_INIT yang sudah obsolete. Kita juga akan melihat mengapa C17 sering menjadi pilihan default untuk compiler modern.
C17: Standar Tanpa Fitur Baru #
Ketika komite WG14 menerbitkan C17 pada Oktober 2018, dokumen standar hanya berisi klarifikasi terhadap C11—tidak ada keyword baru, tidak ada header baru, tidak ada tipe baru. Perubahan utamanya adalah:
- Klarifikasi wording untuk
_Static_assert,_Alignas, dan anonymous struct/union. - Definisi ulang alokasi VLA agar tidak lagi menjadi undefined behavior saat ukuran berubah.
ATOMIC_VAR_INITditandai obsolete karena inisialisasi_Atomic int x = 0;langsung sudah cukup aman sejak C11.- Penegasan
__has_includesebagai feature test macro yang diperlakukan sebagai predefined macro.
Program berikut memperlihatkan bahwa kode yang sama dapat dikompilasi dengan -std=c11 atau -std=c17 dan menghasilkan perilaku yang sama—perbedaan hanya pada nilai __STDC_VERSION__.
// File: c17_1.c - C17 adalah bugfix release; tidak ada fitur baru
#include <stdio.h>
#include <stdatomic.h>
int main(void) {
// __STDC_VERSION__ untuk C17 adalah 201710L
#ifdef __STDC_VERSION__
printf("__STDC_VERSION__ : %ldL\n", __STDC_VERSION__);
#endif
// _Static_assert masih ada (ditambah C11, diperbaiki wording di C17)
_Static_assert(sizeof(char) == 1, "char harus 1 byte");
// _Atomic masih bekerja sama seperti C11
_Atomic int x = 0;
atomic_fetch_add(&x, 42);
printf("x setelah atomic_fetch_add : %d\n", x);
return 0;
}Compile dan jalankan dengan kedua flag:
gcc -std=c11 -Wall -Wextra -pedantic -o c17_1_c11 c17_1.c && ./c17_1_c11
gcc -std=c17 -Wall -Wextra -pedantic -o c17_1_c17 c17_1.c && ./c17_1_c17Output yang Dihasilkan (gcc -std=c11):
__STDC_VERSION__ : 201112L
x setelah atomic_fetch_add : 42Output yang Dihasilkan (gcc -std=c17):
__STDC_VERSION__ : 201710L
x setelah atomic_fetch_add : 42Satu-satunya perbedaan output adalah nilai __STDC_VERSION__ (201112L vs 201710L). Perilaku runtime identik karena C17 tidak menambahkan fitur baru.
Macro Feature Test di C17 #
C11 memperkenalkan dua macro feature test opsional: __STDC_NO_ATOMICS dan __STDC_NO_THREADS. Jika compiler tidak mendukung atomics atau threads.h, macro tersebut harus didefinisikan. C17 menegaskan bahwa compiler modern wajib mendefinisikan macro ini (atau tidak) secara konsisten. Program berikut memeriksa keduanya dan status ATOMIC_VAR_INIT:
// File: c17_2.c - Macro feature test C17
#include <stdio.h>
#include <stdatomic.h>
int main(void) {
printf("C17 (ISO/IEC 9899:2018) hanya berisi perbaikan defect report.\n");
// ATOMIC_VAR_INIT: masih ada di C17 tetapi obsolete
#ifdef ATOMIC_VAR_INIT
printf("ATOMIC_VAR_INIT terdefinisi : ya (obsolete di C17)\n");
#else
printf("ATOMIC_VAR_INIT terdefinisi : tidak\n");
#endif
// __STDC_NO_ATOMICS dan __STDC_NO_THREADS (opsional di C11/C17)
#ifdef __STDC_NO_ATOMICS
printf("__STDC_NO_ATOMICS : defined (atomics TIDAK didukung)\n");
#else
printf("__STDC_NO_ATOMICS : tidak defined (atomics didukung)\n");
#endif
#ifdef __STDC_NO_THREADS
printf("__STDC_NO_THREADS : defined (threads.h TIDAK didukung)\n");
#else
printf("__STDC_NO_THREADS : tidak defined (threads.h didukung)\n");
#endif
// Penggunaan ATOMIC_VAR_INIT (cara lama, obsolete di C17)
_Atomic int counter_old = ATOMIC_VAR_INIT(0);
// Cara baru yang lebih sederhana
_Atomic int counter_new = 0;
atomic_fetch_add(&counter_old, 10);
atomic_fetch_add(&counter_new, 5);
printf("counter_old : %d\n", counter_old);
printf("counter_new : %d\n", counter_new);
return 0;
}Compile dan jalankan:
gcc -std=c17 -Wall -Wextra -pedantic -o c17_2 c17_2.c
./c17_2Output yang Dihasilkan:
C17 (ISO/IEC 9899:2018) hanya berisi perbaikan defect report.
ATOMIC_VAR_INIT terdefinisi : ya (obsolete di C17)
__STDC_NO_ATOMICS : tidak defined (atomics didukung)
__STDC_NO_THREADS : tidak defined (threads.h didukung)
counter_old : 10
counter_new : 5Mari kita telaah baris-baris kode di atas:
- Baris 11-14 (
#ifdef ATOMIC_VAR_INIT ... #endif): MacroATOMIC_VAR_INITdiperkenalkan di C11 sebagai cara portabel menginisialisasi_Atomicvariable:_Atomic int x = ATOMIC_VAR_INIT(0);. Di C17, macro ini ditandai obsolete karena_Atomic int x = 0;langsung sudah terdefinisi memiliki perilaku atomic initialization yang sama. - Baris 17-22 (
#ifdef __STDC_NO_ATOMICS ... #endif): Jika compiler mendefinisikan macro ini, berarti compiler tersebut tidak mendukungstdatomic.h. Di GCC, Clang, dan MSVC modern, macro ini tidak didefinisikan, yang berarti atomics didukung penuh. Compiler embedded tertentu (mis. SDCC) mungkin mendefinisikannya. - Baris 24-29 (
#ifdef __STDC_NO_THREADS ... #endif): Sama seperti atomics, tetapi untukthreads.h. GCC/Clang mendukungthreads.hvia pthread. MSVC tidak menyertakanthreads.h—tetapi MSVC juga tidak mendefinisikan__STDC_NO_THREADSsecara konsisten, sehingga kita tidak bisa mengandalkan macro ini di MSVC. - Baris 32 (
_Atomic int counter_old = ATOMIC_VAR_INIT(0);): Cara lama inisialisasi atomic. Masih sah di C17 tetapi akan dihapus di C23. Compiler mungkin mengeluarkan warning-Wdeprecatedsaat kode ini dipakai. - Baris 34 (
_Atomic int counter_new = 0;): Cara baru yang sejak awal C11 sebenarnya sudah cukup. Standar C11 awal ambigu apakah ini atomic initialization; C17 mengklarifikasi bahwa ini sah dan setara denganATOMIC_VAR_INIT(0).
Kapan Memilih C17 #
C17 sering disebut “standar stabil” karena tidak menambahkan fitur baru, sehingga compiler modern dapat mematuhinya tanpa risiko implementasi setengah-jadi. GCC sejak versi 8, Clang sejak versi 6, dan MSVC sejak versi 2019 16.8 mendukung C17 penuh. Untuk proyek yang membutuhkan baseline stabil dan kompatibilitas maksimum antar compiler (termasuk Windows), -std=c17 adalah pilihan terbaik. Bab berikutnya akan membahas C23 yang menambahkan nullptr, constexpr, dan attribute [[nodiscard]]/[[deprecated]]—lompatan fitur terbesar sejak C11.