Standar C99 mengatakan dalam 6.5.16: 2:
Operator penugasan harus memiliki nilai yang dapat dimodifikasi sebagai operan kirinya.
dan di 6.3.2.1:1:
Lvalue yang dapat dimodifikasi adalah lvalue yang tidak memiliki tipe array, tidak memiliki tipe tidak lengkap, tidak memiliki tipe const-kualifikasi, dan jika itu adalah struktur atau gabungan, tidak memiliki anggota (termasuk, secara rekursif, setiap anggota atau elemen dari semua agregat atau serikat yang terkandung) dengan tipe const-kualifikasi.
Sekarang, mari kita pertimbangkan non- const
struct
dengan const
bidang.
typedef struct S_s {
const int _a;
} S_t;
Secara standar, kode berikut adalah perilaku tidak terdefinisi (UB):
S_t s1;
S_t s2 = { ._a = 2 };
s1 = s2;
Masalah semantik dengan hal ini adalah bahwa entitas terlampir ( struct
) harus dianggap dapat ditulis (non-read-only), dilihat dari tipe entitas yang dinyatakan ( S_t s1
), tetapi tidak boleh dianggap dapat ditulis oleh kata-kata standar (2 klausa di atas) karena const
bidang _a
. Standar membuatnya tidak jelas bagi seorang programmer yang membaca kode bahwa tugas itu sebenarnya adalah UB, karena tidak mungkin untuk mengatakan bahwa tanpa definisi struct S_s ... S_t
tipe.
Selain itu, akses baca-saja ke bidang ini hanya ditegakkan secara sintaksis pula. Tidak mungkin beberapa const
bidang non const
struct
-benar-benar ditempatkan untuk penyimpanan read-only. Tetapi kata-kata standar seperti itu melarang kode yang dengan sengaja membuang const
kualifikasi bidang dalam prosedur aksesor bidang ini, seperti itu ( Apakah itu ide yang baik untuk menyamakan kualifikasi bidang struktur di C? ):
(*)
#include <stdlib.h>
#include <stdio.h>
typedef struct S_s {
const int _a;
} S_t;
S_t *
create_S(void) {
return calloc(sizeof(S_t), 1);
}
void
destroy_S(S_t *s) {
free(s);
}
const int
get_S_a(const S_t *s) {
return s->_a;
}
void
set_S_a(S_t *s, const int a) {
int *a_p = (int *)&s->_a;
*a_p = a;
}
int
main(void) {
S_t s1;
// s1._a = 5; // Error
set_S_a(&s1, 5); // OK
S_t *s2 = create_S();
// s2->_a = 8; // Error
set_S_a(s2, 8); // OK
printf("s1.a == %d\n", get_S_a(&s1));
printf("s2->a == %d\n", get_S_a(s2));
destroy_S(s2);
}
Jadi, untuk beberapa alasan, agar keseluruhan struct
dapat dibaca - hanya cukup untuk menyatakannyaconst
const S_t s3;
Tetapi untuk keseluruhan struct
menjadi non-read-only saja tidak cukup untuk menyatakannya tanpa const
.
Apa yang saya pikir akan lebih baik, adalah:
- Untuk membatasi penciptaan non-
const
struktur denganconst
bidang, dan mengeluarkan diagnostik dalam kasus seperti itu. Itu akan memperjelas bahwastruct
bidang yang hanya baca hanya baca itu sendiri. - Untuk mendefinisikan perilaku dalam kasus menulis ke
const
bidang milik non-const
struct untuk membuat kode di atas (*) sesuai dengan Standar.
Kalau tidak, tingkah lakunya tidak konsisten dan sulit dipahami.
Jadi, apa alasan C Standard mempertimbangkan const
-ness secara rekursif, seperti yang dikatakannya?