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
文件输出时导致更易读的更改。
抱歉,如果我问的是一个愚蠢的问题,但我猜是因为搜索词笨拙,我找不到答案
如果我声明三个变量如下
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
文件输出时导致更易读的更改。