Proposal: readable and writable attributes on variables

Jens Bauer
Fri Sep 2 17:35:00 GMT 2016

Hi Martin (and all other list members).

On Thu, 1 Sep 2016 09:04:10 -0600, Martin Sebor wrote:
> On 08/31/2016 04:56 AM, Jens Bauer wrote:
>>>    __attribute__ ((not_readable)) int write_only;
>>>    int *preadwrite = &write_only;
>> Would it not be possible to bring a warning in such cases ?
>> -or would that actually require a kludge ?
> I would expect it to be easier to issue a warning than to add support
> for a whole new type qualifier to the two GCC front ends (C and C++).
> The latter, of course, has the advantage of a more robust solution.

A new type qualifier would be great, but I think it would be more correct to propose that as an extension of the C-language (and I don't even know who's in charge of those standards).
Somehow 'const' and 'not_writable' is the exact same thing, but naming a keyword for 'not_readable', which can be combined with 'const' is kinda ... difficult, I think. ;)

>> #define __NA	__attribute__((not_readable,not_writable)) /* not 
>> available or no access */
>> typedef struct {
>>    __NA uint32_t		reserved[2];	/*  */
> This could be implemented via unnamed bit-fields:
>   uint32_t: 32;
>   uint32_t: 32;

That is actually awesome. I did not know that this was possible.
(I've been programming since the 80's and it seems I'm in need of a C-course).

Is it possible to make unnamed arrays too ?

>> USART3->ODR = byteToSend;
>> receivedByte = USART3->IDR;
> I'm not sure I understand the purpose of using the union here but
> that's probably not important for your proposal.

The example might look a bit silly, but the idea is that input data and output data are two different registers placed on the same address (!)
Writing a 0x41 to ODR and reading IDR immediately after may give you a result like 0x0D.
-Eg. IDR is the Receive Data Register, ODR is the Transmit Data Register.
Thus they differ.
On some microcontrollers in a family, DR registers may share the same address on one implementation, but a different implementation, they could be two different addresses.

(On the Atari ST's floppy disk controller, you wrote one register, and at the register's address offset two bytes, you would read the data you just wrote).

>> Normally, __I, __O and __IO are defined as follows in the CMSIS 
>> include files:
>> #ifdef __cplusplus
>>    #define __I   volatile          /*!< Defines 'read only' permissions */
>> #else
>>    #define __I   volatile const    /*!< Defines 'read only' permissions */
>> #endif
>> #define __O     volatile          /*!< Defines 'write only' permissions */
>> #define __IO    volatile          /*!< Defines 'read / write' 
>> permissions */
>> -That means for C++, __I does not work entirely as intended; it was 
>> probably done this way due to RTTI.
>> I believe that in this case an attribute would not have this problem ?
> I can't imagine what impact RTTI might have on this. I'd expect
> "__attribute__((not_writable))" to map to "const" with no need for
> the attribute.

I believe it's due to that people mix C and C++; they use C headers for C++ projects (they kinda have to).
As #define macros are unaffected by extern "C" { ... }, a macro that defines __IO as being const will still generate a C++ symbol when the file is compiled by the C++ compiler. Linking the file with a C file will probably result in an undefined symbol, because the linker looks for the C++ symbol.
-But it's definitely not impossible to use const in this case, and the above might be a solution to quickly fix some build-errors that occurs in certain combinations. I've not thought about all the possible aspects of why it is only declared const for C, though.

>> __O can not prohibit reading.
>> Some hardware registers react upon 'access'; eg. if read, it becomes 
>> zero, if written, only the set bits are changed.
>> __O currently cannot prevent reading such registers.
> Understood.  I think a write-only attribute or type qualifier would
> make sense.  Until/unless it's implemented I would recommend to work
> around its absence by hiding access to the registers behind a read-
> only and write-only functional API.

I'll begin writing an official proposal/enhancement request, with as concise information as I can.

I very much appreciate the kindness and aspects from both you and Florian, and I hope that many will benefit from the changes. :)

I'd also like to thank every developer who has been part of developing GCC. As it had an impact on the entire World, the World would look completely different without these tools; thank you all for making such an awesome and robust platform independent tool of such high quality!


More information about the Gcc mailing list