C99 standardı 6.5.16: 2'de diyor:
Bir atama operatörü, sol işlenen olarak değiştirilebilir bir değere sahip olacaktır.
ve 6.3.2.1:1'de:
Değiştirilebilir bir değer, dizi türüne sahip olmayan, tamamlanmamış bir türe sahip olmayan, sabit nitelikli bir türe sahip olmayan ve bir yapı veya birleşim olan herhangi bir üyesi olmayan (yinelemeli olarak herhangi bir üye dahil) bir değerdir. veya içerilen tüm agregaların veya birliklerin elemanı).
Şimdi, alan olmayan const structbir constalanı ele alalım .
typedef struct S_s {
const int _a;
} S_t;
Standart olarak, aşağıdaki kod tanımsız davranıştır (UB):
S_t s1;
S_t s2 = { ._a = 2 };
s1 = s2;
Bununla ilgili anlamsal sorun, ekteki varlık ( struct) 'ın beyan edilen kuruluş türü ( ) ile değerlendirilerek yazılabilir (salt okunur olmayan S_t s1) olarak kabul edilmesi, ancak standardın (2 fıkraları ile yazılabilir olarak kabul edilmemesi) üstte) constalan nedeniyle _a. Standart, bir programcının atamanın gerçekte bir UB olduğunu kodunu okumasını netleştirmez, çünkü struct S_s ... S_ttür tanımının w / o olduğunu söylemek imkansızdır .
Dahası, alana salt okunur erişim sadece sözdizimsel olarak zorunlu kılınmıştır. Bazı constnon-non alanlarının const structsalt okunur depolamaya yerleştirilmesinin hiçbir yolu yoktur . Ancak bu tür standart ifadeler, constbu alanların erişimci prosedürlerindeki alanların niteleyicisini kasıtlı olarak ortadan kaldıran kodu , bu şekilde ( C'deki yapı alanlarını daraltmak iyi bir fikir mi? ):
(*)
#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);
}
Bu nedenle, bir nedenden dolayı, bir bütünün structsalt okunur olması için bunu beyan etmek yeterlidirconst
const S_t s3;
Ancak bir bütünün structsalt okunur olmaması için, bunu w / o olarak bildirmek yeterli değildir const.
Ne daha iyi olacağını düşünüyorum, ya da:
constYapı olmayan yapıların oluşturulmasınıconstalanlarla sınırlamak ve böyle bir durumda teşhis koymak. Bu,structiçerdiği salt okunur alanların salt okunur olduğunu açıkça ortaya koyacaktır.- Yapıya
constait olmayan bir alana yazma durumunda davranışı,constyukarıdaki kodu (*) Standart ile uyumlu hale getirecek şekilde tanımlamak .
Aksi takdirde davranış tutarlı ve anlaşılması zor değildir.
Öyleyse, C Standardının, const-sayıya koyduğu gibi, özyineliği tekrar tekrar düşünmesinin nedeni nedir?