C中的volatile关键字,是否所有变量都标记为volatile?

volatile keyword in C, are all variables marked as volatile?

抱歉,如果我问的是一个愚蠢的问题,但我猜是因为搜索词笨拙,我找不到答案

如果我声明三个变量如下

volatile uint16_t a, b, c;

所有三个变量都声明为易变的吗?

或者我真的不应该连续声明多个变量,而是应该这样做:

volatile uint16_t a;
volatile uint16_t b;
volatile uint16_t c;

我们可以检查编译器生成的程序集,看看它是否优化了变量。

当我检查这个简单的程序时:

#include <stdio.h>
#include <stdint.h>

int main(void)
{
    uint16_t a = 1, b = 1, c = 1;
    printf("%hu", a);
    printf("%hu", b);
    printf("%hu", c);
}

-O3 (link) 处生成的程序集是:

.LC0:
        .string "%hu"
main:
        sub     rsp, 8
        mov     esi, 1
        mov     edi, OFFSET FLAT:.LC0
        xor     eax, eax
        call    printf
        mov     esi, 1
        mov     edi, OFFSET FLAT:.LC0
        xor     eax, eax
        call    printf
        mov     esi, 1
        mov     edi, OFFSET FLAT:.LC0
        xor     eax, eax
        call    printf
        xor     eax, eax
        add     rsp, 8
        ret

这里很明显,变量已经被优化掉了,1被用作参数而不是变量。

当我将 uint16_t a = 1, b = 1, c = 1; 替换为 volatile uint16_t a = 1, b = 1, c = 1; 时,生成的程序集 (link) 是:

main:
        sub     rsp, 24
        mov     edx, 1
        mov     ecx, 1
        mov     eax, 1
        mov     WORD PTR [rsp+10], ax
        mov     edi, OFFSET FLAT:.LC0
        xor     eax, eax
        mov     WORD PTR [rsp+12], dx
        mov     WORD PTR [rsp+14], cx
        movzx   esi, WORD PTR [rsp+10]
        call    printf
        movzx   esi, WORD PTR [rsp+12]
        mov     edi, OFFSET FLAT:.LC0
        xor     eax, eax
        call    printf
        movzx   esi, WORD PTR [rsp+14]
        mov     edi, OFFSET FLAT:.LC0
        xor     eax, eax
        call    printf
        xor     eax, eax
        add     rsp, 24
        ret

在这里,volatile 对 所有 变量都正常工作。变量已创建但未优化。

相比之下,如果我们将 volatile uint16_t a = 1, b = 1, c = 1; 替换为 volatile uint16_t a = 1; uint16_t b = 1, c = 1;,我们会看到只有 a 没有优化掉 (link):

main:
        sub     rsp, 24
        mov     eax, 1
        mov     edi, OFFSET FLAT:.LC0
        mov     WORD PTR [rsp+14], ax
        movzx   esi, WORD PTR [rsp+14]
        xor     eax, eax
        call    printf
        mov     esi, 1
        mov     edi, OFFSET FLAT:.LC0
        xor     eax, eax
        call    printf
        mov     esi, 1
        mov     edi, OFFSET FLAT:.LC0
        xor     eax, eax
        call    printf
        xor     eax, eax
        add     rsp, 24
        ret

If I declare three variables as follows

volatile uint16_t a, b, c;

Will all three variables be declared volatile?

是的,所有 3 个变量都是可变的。

Or should I really not declare multiple variables in a row but instead do:

这跟代码风格和个人喜好有关。通常每行声明一个变量是首选,这样更易​​读、更容易阅读、更容易重构,并且在浏览 diff 文件输出时导致更易读的更改。