volatile access through cast with volatile-qualified type

I’ve seen constructs like the following to write to memory mapped I/O.

*((volatile unsigned int *)0xDEADBEEF) = 0x00;

But is this guaranteed to be a volatile access?1

I started to think about this after I’ve noticed following change in the C standard regarding cast operators:

The C11 spec says following:

N1570, § 6.5.4, ¶ 5:

Preceding an expression by a parenthesized type name converts the value of the expression to the named type. This construction is called a cast.104) […]

N1570, footnote 104):

  1. A cast does not yield an lvalue. Thus, a cast to a qualified type has the same effect as a cast to the unqualified version of the type.

In C17 this has changed to:

N2310, § 6.5.4, ¶ 5:

Preceding an expression by a parenthesized type name converts the value of the expression to the unqualified version of the named type. This construction is called a cast.108) […]

N2310, footnote 108):

  1. A cast does not yield an lvalue.

Both versions also have:

N2310, § 6.5.3.2, ¶ 4:

The unary * operator denotes indirection. […]; if it points to an object, the result is an lvalue designating the object. If the operand has type “pointer to type“, the result has type “type“. […]

So for C17 it should be clear: the above shown code should be the same as *((unsigned int *)0xDEADBEEF) = 0x00;, i.e., the volatile qualifier is dropped and thus this wouldn’t be a volatile access, although we have the volatile in the cast expression.

For C11 I am not sure: if we take the footnote as obligatory, then it shouldn’t be a volatile access either, because “a cast to a qualified type has the same effect as a cast to the unqualified version of the type”; but without that footnote and just the text in (§ 6.5.4, ¶ 5) in mind, I would say it should be a volatile access – or are there some other paragraphs in the spec which make it clear that this should not be a volatile access?


For the sake of completeness: following should be guaranteed to be a volatile access:

volatile unsigned int *mem = (unsigned int *)0xDEADBEEF;
*mem = 0x00;

1Assuming that a write to an object of volatile-qualified type is defined as an access to that object; see following:

N1570, § 6.7.3, ¶ 8:

[…] What constitutes an access to an object that has volatile-qualified type is implementation defined.

0

The two versions of the standard are essentially saying the same thing in two different ways, i.e. that a cast effectively results in a unqualified type.

What you seem to be confused by here is that you’re not actually casting to a qualified type. You’re casting to a pointer (which is unqualified in this case) to a qualified type. The pointer itself is not qualified, but what it points to is.

So this:

*((volatile unsigned int *)0xDEADBEEF) = 0x00;

Is considered volatile access, as the constant 0xDEADBEEF is converted to a pointer (which is not volatile) to a volatile unsigned int, and that pointer is subsequently dereferenced to access the volatile object.

The change in 6.5.4 5 between C 2011 and C 2018:

  • was intended be a correction and clarification, not a change in what is specified (per C 2018 Forward 8), and

  • is not relevant to your example because volatile unsigned int * is not a qualified type.

volatile unsigned int * is a pointer type that has no qualifiers—an object of this type is a pointer that is not volatile. It points to a type that is qualified. The volatile applies to the pointed-to type, not the pointer type, and it is not dropped by the cast. The result of the cast is an volatile unsigned int *, including the volatile.

… that footnote… [“A cast does not yield an lvalue.”]

This means the pointer resulting from the cast is not an lvalue. You could not write ((volatile unsigned int *) 0xDEADBEEF) = p; to change the pointer resulting from the cast, just as you could not write 3+4 = 8; to change the result of 3+4.

When you apply the * operator, that produces an lvalue from the pointer; *((volatile unsigned int *) 0xDEADBEEF) is an lvalue, and it has volatile-qualified type.

On the topic of volatile accesses, C 2024 did make some changes. C 2018 mentions in various places accessing a “volatile object.” C 2024 instead defines a volatile access, in 5.2.2.4:

An access to an object through the use of an lvalue of volatile-qualified type is a volatile access.

and uses this term such as including volatile accesses in observable behavior:

Volatile accesses to objects are evaluated strictly according to the rules of the abstract machine.

I regard this as a clarification of language, not a change of intent. With C 2018, one might think that a volatile object is only one defined with volatile and have some question about * (volatile int *) &x = 3; if x was not defined with volatile. If it was not defined with volatile, does that assignment have to be evaluated as if it were?

C 2024 makes this clear; since a volatile-qualified type is used to access x, it is a volatile access, regardless of how x was defined.

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

volatile access through cast with volatile-qualified type

I’ve seen constructs like the following to write to memory mapped I/O.

*((volatile unsigned int *)0xDEADBEEF) = 0x00;

But is this guaranteed to be a volatile access?1

I started to think about this after I’ve noticed following change in the C standard regarding cast operators:

The C11 spec says following:

N1570, § 6.5.4, ¶ 5:

Preceding an expression by a parenthesized type name converts the value of the expression to the named type. This construction is called a cast.104) […]

N1570, footnote 104):

  1. A cast does not yield an lvalue. Thus, a cast to a qualified type has the same effect as a cast to the unqualified version of the type.

In C17 this has changed to:

N2310, § 6.5.4, ¶ 5:

Preceding an expression by a parenthesized type name converts the value of the expression to the unqualified version of the named type. This construction is called a cast.108) […]

N2310, footnote 108):

  1. A cast does not yield an lvalue.

Both versions also have:

N2310, § 6.5.3.2, ¶ 4:

The unary * operator denotes indirection. […]; if it points to an object, the result is an lvalue designating the object. If the operand has type “pointer to type“, the result has type “type“. […]

So for C17 it should be clear: the above shown code should be the same as *((unsigned int *)0xDEADBEEF) = 0x00;, i.e., the volatile qualifier is dropped and thus this wouldn’t be a volatile access, although we have the volatile in the cast expression.

For C11 I am not sure: if we take the footnote as obligatory, then it shouldn’t be a volatile access either, because “a cast to a qualified type has the same effect as a cast to the unqualified version of the type”; but without that footnote and just the text in (§ 6.5.4, ¶ 5) in mind, I would say it should be a volatile access – or are there some other paragraphs in the spec which make it clear that this should not be a volatile access?


For the sake of completeness: following should be guaranteed to be a volatile access:

volatile unsigned int *mem = (unsigned int *)0xDEADBEEF;
*mem = 0x00;

1Assuming that a write to an object of volatile-qualified type is defined as an access to that object; see following:

N1570, § 6.7.3, ¶ 8:

[…] What constitutes an access to an object that has volatile-qualified type is implementation defined.

0

The two versions of the standard are essentially saying the same thing in two different ways, i.e. that a cast effectively results in a unqualified type.

What you seem to be confused by here is that you’re not actually casting to a qualified type. You’re casting to a pointer (which is unqualified in this case) to a qualified type. The pointer itself is not qualified, but what it points to is.

So this:

*((volatile unsigned int *)0xDEADBEEF) = 0x00;

Is considered volatile access, as the constant 0xDEADBEEF is converted to a pointer (which is not volatile) to a volatile unsigned int, and that pointer is subsequently dereferenced to access the volatile object.

The change in 6.5.4 5 between C 2011 and C 2018:

  • was intended be a correction and clarification, not a change in what is specified (per C 2018 Forward 8), and

  • is not relevant to your example because volatile unsigned int * is not a qualified type.

volatile unsigned int * is a pointer type that has no qualifiers—an object of this type is a pointer that is not volatile. It points to a type that is qualified. The volatile applies to the pointed-to type, not the pointer type, and it is not dropped by the cast. The result of the cast is an volatile unsigned int *, including the volatile.

… that footnote… [“A cast does not yield an lvalue.”]

This means the pointer resulting from the cast is not an lvalue. You could not write ((volatile unsigned int *) 0xDEADBEEF) = p; to change the pointer resulting from the cast, just as you could not write 3+4 = 8; to change the result of 3+4.

When you apply the * operator, that produces an lvalue from the pointer; *((volatile unsigned int *) 0xDEADBEEF) is an lvalue, and it has volatile-qualified type.

On the topic of volatile accesses, C 2024 did make some changes. C 2018 mentions in various places accessing a “volatile object.” C 2024 instead defines a volatile access, in 5.2.2.4:

An access to an object through the use of an lvalue of volatile-qualified type is a volatile access.

and uses this term such as including volatile accesses in observable behavior:

Volatile accesses to objects are evaluated strictly according to the rules of the abstract machine.

I regard this as a clarification of language, not a change of intent. With C 2018, one might think that a volatile object is only one defined with volatile and have some question about * (volatile int *) &x = 3; if x was not defined with volatile. If it was not defined with volatile, does that assignment have to be evaluated as if it were?

C 2024 makes this clear; since a volatile-qualified type is used to access x, it is a volatile access, regardless of how x was defined.

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