What’s the reason for C standard to consider const-ness recursively?

The C99 standard says in 6.5.16:2:

An assignment operator shall have a modifiable lvalue as its left
operand.

and in 6.3.2.1:1:

A modifiable lvalue is an lvalue that does not have array type, does
not have an incomplete type, does not have a const-qualified type, and
if it is a structure or union, does not have any member (including,
recursively, any member or element of all contained aggregates or
unions) with a const-qualified type.

Now, let’s consider a non-const struct with a const field.

typedef struct S_s {
    const int _a;
} S_t;

By standard, the following code is undefined behavior (UB):

S_t s1;
S_t s2 = { ._a = 2 };
s1 = s2;

The semantic problem with this is that the enclosing entity (struct) should be considered writable (non-read-only), judging by the declared type of the entity (S_t s1), but should not be considered writable by the wording of standard (the 2 clauses on the top) because of const field _a. The Standard makes it unclear for a programmer reading the code that the assignment is actually a UB, because it’s impossible to tell that w/o the definition of struct S_s ... S_t type.

Moreover, the read-only access to the field is only enforced syntactically anyway. There’s no way some const fields of non-const struct are going really be placed to read-only storage. But such wording of standard outlaws the code which deliberately casts away the const qualifier of fields in accessor procedures of these fields, like so (Is it a good idea to const-qualify the fields of structure in 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 == %dn", get_S_a(&s1));
    printf("s2->a == %dn", get_S_a(s2));

    destroy_S(s2);
}

So, for some reason, for an entire struct to be read-only it’s enough to declare it const

const S_t s3;

But for an entire struct to be non-read-only it’s not enough to declare it w/o const.

What I think would be better, is either:

  1. To constrain the creation of non-const structures with const fields, and issue a diagnostic in such a case. That would make it clear that the struct containing read-only fields is read-only itself.
  2. To define the behavior in case of write to a const field belonging to a non-const struct as to make the code above (*) compliant to the Standard.

Otherwise the behavior is not consistent and hard to understand.

So, what’s the reason for C Standard to consider const-ness recursively, as it puts it?

3

So, what’s the reason for C Standard to consider const-ness recursively, as it puts it?

From a type perspective alone, not doing so would be unsound (in other words: terribly broken and intentionally unreliable).

And that’s because of what “=” means on a struct: it is a recursive assignment. It follows that eventually you have a s1._a = <value> happening “inside the typing rules”. If the standard allows this for “nested” const fields, its adding a serious inconsistency in its type system definition as an explicit contradiction (might as well throw the const feature away, as it just became useless and unreliable by its very definition).

Your solution (1), as far as I understand it, is unnecessarily forcing the entire structure to be const whenever one of its fields is const. In this way, s1._b = b would be illegal for a non-const ._b field on a non-const s1 containing a const a.

2

The reason is that read-only fields are read-only. No big surprise there.

You’re mistakenly assuming that the only effect is on placement in ROM, which indeed is impossible when there are adjacent non-const fields. In reality, optimizers may assume const expressions are not written to, and optimize based on that. Of course that assumption doesn’t hold when non-const aliases exist.

Your solution (1) breaks existing legal and reasonable code. That won’t happen. Your solution (2) pretty much removes the meaning of const on members. While this won’t break existing code, it seems to lack a rationale.

8

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa

What’s the reason for C standard to consider const-ness recursively?

The C99 standard says in 6.5.16:2:

An assignment operator shall have a modifiable lvalue as its left
operand.

and in 6.3.2.1:1:

A modifiable lvalue is an lvalue that does not have array type, does
not have an incomplete type, does not have a const-qualified type, and
if it is a structure or union, does not have any member (including,
recursively, any member or element of all contained aggregates or
unions) with a const-qualified type.

Now, let’s consider a non-const struct with a const field.

typedef struct S_s {
    const int _a;
} S_t;

By standard, the following code is undefined behavior (UB):

S_t s1;
S_t s2 = { ._a = 2 };
s1 = s2;

The semantic problem with this is that the enclosing entity (struct) should be considered writable (non-read-only), judging by the declared type of the entity (S_t s1), but should not be considered writable by the wording of standard (the 2 clauses on the top) because of const field _a. The Standard makes it unclear for a programmer reading the code that the assignment is actually a UB, because it’s impossible to tell that w/o the definition of struct S_s ... S_t type.

Moreover, the read-only access to the field is only enforced syntactically anyway. There’s no way some const fields of non-const struct are going really be placed to read-only storage. But such wording of standard outlaws the code which deliberately casts away the const qualifier of fields in accessor procedures of these fields, like so (Is it a good idea to const-qualify the fields of structure in 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 == %dn", get_S_a(&s1));
    printf("s2->a == %dn", get_S_a(s2));

    destroy_S(s2);
}

So, for some reason, for an entire struct to be read-only it’s enough to declare it const

const S_t s3;

But for an entire struct to be non-read-only it’s not enough to declare it w/o const.

What I think would be better, is either:

  1. To constrain the creation of non-const structures with const fields, and issue a diagnostic in such a case. That would make it clear that the struct containing read-only fields is read-only itself.
  2. To define the behavior in case of write to a const field belonging to a non-const struct as to make the code above (*) compliant to the Standard.

Otherwise the behavior is not consistent and hard to understand.

So, what’s the reason for C Standard to consider const-ness recursively, as it puts it?

3

So, what’s the reason for C Standard to consider const-ness recursively, as it puts it?

From a type perspective alone, not doing so would be unsound (in other words: terribly broken and intentionally unreliable).

And that’s because of what “=” means on a struct: it is a recursive assignment. It follows that eventually you have a s1._a = <value> happening “inside the typing rules”. If the standard allows this for “nested” const fields, its adding a serious inconsistency in its type system definition as an explicit contradiction (might as well throw the const feature away, as it just became useless and unreliable by its very definition).

Your solution (1), as far as I understand it, is unnecessarily forcing the entire structure to be const whenever one of its fields is const. In this way, s1._b = b would be illegal for a non-const ._b field on a non-const s1 containing a const a.

2

The reason is that read-only fields are read-only. No big surprise there.

You’re mistakenly assuming that the only effect is on placement in ROM, which indeed is impossible when there are adjacent non-const fields. In reality, optimizers may assume const expressions are not written to, and optimize based on that. Of course that assumption doesn’t hold when non-const aliases exist.

Your solution (1) breaks existing legal and reasonable code. That won’t happen. Your solution (2) pretty much removes the meaning of const on members. While this won’t break existing code, it seems to lack a rationale.

8

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật