我有一段代码,我试图返回指向的值的平方*ptr.
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
b = *ptr;
return a * b;
}
main()
{
int a=8,t;
t=square(&a);
printf("%d",t);
}
Run Code Online (Sandbox Code Playgroud)
它对我来说很好,但是这段代码的作者说它可能因为以下原因而无法工作:
因为它可能*ptr会意外地改变,a和b有可能不同.因此,此代码可能返回一个不是正方形的数字!正确的方法是
long square(volatile int *ptr)
{
int a;
a = *ptr;
return a * a;
}
Run Code Online (Sandbox Code Playgroud)
我真的很想知道他为什么这样说?
在开发仅标头的库时,我想确保将给定的字符串嵌入使用标头的所有二进制文件中,即使编译器配置为优化未使用的常量,并且二进制文件也被剥离。
嵌入不应有任何副作用(除了使生成的二进制文件更大一点以外)。
我不知道人们将如何使用标题,但是
我的小尝试等于:
static char frobnozzel_version_string[] = "Frobnozzel v0.1; © 2019 ACME; GPLv3";
Run Code Online (Sandbox Code Playgroud)
...,但是在构建过程中很容易将其删除(由于实际未使用该字符串,因此对于优化编译器而言很容易被攻击)。
因此问题是:是否可以在包含给定标头的二进制文件中嵌入一个字符串,而该字符串不会被构建“发布”二进制文件的常规策略优化/删除?
我知道,任何使用该库的人都可以(手动)删除我输入的内容,但是让我们假设,人们只是按原样使用标题。
上下文:所涉及的标头是根据GPL发布的,我希望能够检查用户是否确实遵守了许可证。
我正在研究Robert Love的Linux内核开发Linux内核.
如您所知,本书使用旧版Linux.它是2.6版本
atomic_t有"volatile int counter".但是新Linux版本的atomic_t的"int counter"并不易变.为什么这种挥发性已经消失了?
我读过volatile关键字,但我不知道在什么情况下我应该使用它.
当内存(变量)得到更新并且进程没有意识到这一点?
在什么情况下驱动程序应该使用volatile变量?
c compiler-construction operating-system volatile linux-device-driver
我最近一直在努力学习嵌入式系统编程.volatile在声明变量时,我观察到关键字限定符的使用率相当高?
volatile在嵌入式系统编程中声明变量时有什么意义?
基本上应该使用关键词.我确实读过有关编译器优化和关键字使用的内容.还有与内存映射寄存器有关的东西.
例如,我读了这篇StackOverflow帖子,但我不明白它是如何在嵌入式环境中应用的.更具体地说,我不明白何时应该使用关键词.我确实读过有关编译器优化和关键字使用的内容.还有一些与内存映射寄存器相关的东西,但我不明白何时使用它.
考虑以下代码示例:
int main(void)
{
volatile int a;
static volatile int b;
volatile int c;
c = 20;
static volatile int d;
d = 30;
volatile int e = 40;
static volatile int f = 50;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
没有volatile编译器可以优化掉所有变量,因为它们永远不会被读取.
我认为a并且b可以被优化掉,因为它们完全未使用,请参阅未使用的volatile变量.
我认为c并且d因为它们被写入而无法删除,并且必须实际发生对volatile变量的写入.e应该相当于c.
GCC不会优化掉f,但它也不会发出任何写入指令.在数据部分中设置50.LLVM(clang)f完全删除.
这些陈述是真的吗?
我想知道在以下情况下,临时volatile限定符是否会产生正确的行为.假设ISR收集数组中的值,并且一旦收集到足够的值,它就表示准备就绪.
int array[10]; // observe no volatile here
int idx = 0; // neither here
volatile bool ready = false; // but here
Run Code Online (Sandbox Code Playgroud)
这里的ISR是伪代码
ISR() {
if (idx < 10)
array[idx++] = ...;
ready = (idx >= 10);
}
Run Code Online (Sandbox Code Playgroud)
假设我们可以保证这array将是只读后 ready发出信号,和元素是通过特定的方法来访问只:
int read(int idx) {
// temporary volatile semantics
volatile int *e = (volatile int*)(array + idx);
return *e;
}
Run Code Online (Sandbox Code Playgroud)
这似乎是根据cpp-reference允许的
向volatile类型转换非易失性值无效.要使用易失性语义访问非易失性对象,必须将其地址强制转换为指向易失性的指针,然后必须通过该指针进行访问.
为了完整起见,主程序执行以下操作
void loop() {
if (ready) {
int …Run Code Online (Sandbox Code Playgroud) 我知道volatile关键字,
volatile int k=7;
Run Code Online (Sandbox Code Playgroud)
我们提示编译器可以随时更改变量但是简单
int k=7呢?我们可以随时更改它,因为它不是恒定的吗?有什么不同吗?
以下是在运行Barrelfish操作系统时在Pandaboard上闪烁LED的一些代码.我的问题是,为什么不把LED的闪光灯,如果"挥发"关键字是从的定义中删除gpio_oe和gpio_dataout.
static volatile uint32_t *gpio_oe = (uint32_t *)(GPIO_BASE + 0x0134);
static volatile uint32_t *gpio_dataout = (uint32_t *)(GPIO_BASE + 0x013C);
void led_flash
{
// Enable output
*gpio_oe &= (~(1 << 8));
// Toggle LED on and off till eternity
while(true)
{
*gpio_dataout ^= (1 << 8); // Set means LED on; Clear means LED off
time_delay(); // To give blinking effect
}
}
Run Code Online (Sandbox Code Playgroud)
我知道如果变量的值可以通过程序外的源自发地改变,则需要使用volatile.但我在这里看不到这样的情况.编译器执行什么优化会使整个while循环闪烁LED无意义?这种优化背后的逻辑是什么,即.这种优化有意义的合法案例?