What is the correct way to tell the compiler that I want the variable to always be stored in a register?

Reading the answers to this question , it occurred to me that it was registerno longer a valid storage specifier in C ++ 17. Some comments even suggest that the compiler has already ignored several times register.

I am using GCC 6.x with an ARM Cortex-M MCU and have a piece of code with a built-in assembly that is absolutely required to have a variable in the register. I used to assume that the keyword registerwould do this for me, but apparently it doesn't.

  • In modern C ++, what is the right way to ensure that the compiler always uses case for a given variable?
  • If there is no standard method, is there such a GCC method? Maybe some attribute? Or a keyword for the compiler?

EDIT . Why do I need to store something in the registry?
I implement a non-blocking buffer with ARM LDREX/ instructions STREX. I need to save the result of the ARM instruction LDREXin the register, since storing it in memory will lead to the defeat of the entire mechanism on the Cortex-M.

EDIT : sample code.

This is a piece of code cut from a ring buffer to illustrate the point of the question. Objects of interest __LDREXW, __STREXWand __CLREX, which are defined in cmsis_gcc.h. They are integral features of the ARM synchronization primitives. I use them to implement a locking mechanism.

template<typename T, uint32_t maxCount>
class RingBuffer final {

    __attribute__((aligned(8)))
    T buffer[maxCount];
    uint32_t start;
    uint32_t end;

    bool pushBack(const T &item) {
        register uint32_t exclusiveEnd;
        register uint32_t oldEnd;

        do {
            // Load current end value exclusively
            exclusiveEnd = __LDREXW(&end);
            __DMB();

            // Remember old end value so that
            // we can store the item at that location
            oldEnd = exclusiveEnd;

            // Check if ring buffer is full
            if (isFull()) {
                __CLREX();
                __DMB();
                return false;
            }

            // Figure out correct new value
            if (exclusiveEnd == (maxCount - 1)) {
                exclusiveEnd = 0;
            }
            else {
                exclusiveEnd ++;
            }

            // Attempt to store new end value
        } while (0 != __STREXW(exclusiveEnd, &end));
        __CLREX();
        __DMB();

        // Store new item
        //memcpy(buffer + oldEnd, &item, sizeof(T));
        buffer[oldEnd] = item;
        return true;
    }

    // ... other methods ...

}

LDREX :

Cortex-M4 ( Cortex-M4 TRM), , , LDREX, , STREX .

: " ", ..

+4
2

, , ?

( ++ C-). , .

:

  • C ++ (, C11 ++ 14 ++ 17) , , register ( ) .

  • ( ) , .

  • , , ( , ).

, , GCC . ( , ).

, , . (, g++ -O3 -mtune=), . (, g++ -O3 -fverbose-asm -S).

Cortex-M4 ( Cortex-M4 TRM),

( GCC), , ,

, ( , C ++!) -ffixed- reg.

: , . , (, , ) GCC (, GCC 7), , - , ?

+3

register ++, , 1998 . , .

++ (, , -), , .

, . , ( , ). , , . ( , ), .

- , , , ( ..).

, - , ++. ( - , , ). , - .

, register , , , .

- .

, register , , , , , , - .

: , - , , , , . , , , , .

, .

- , - , , .

+2

Source: https://habr.com/ru/post/1679971/


All Articles