为什么 ISO C 禁止将非标量转换为同一类型
Why does ISO C forbid casting nonscalar to the same type
struct Foo {
int dummy;
} bar;
int main(void)
{
/* This statement causes GCC to produce the warning:
* ISO C forbids casting nonscalar to the same type */
(volatile struct Foo)bar;
/* The warning may be silenced like so.
* Is this form superior or just trickier? Why? */
*(volatile struct Foo *)&bar;
return 0;
}
compiler/standard要防的是什么邪?
背景故事:
有问题的真正代码是使用 ISR 和后台共享的循环 buffer/queue。后台代码不断轮询队列。我希望避免悲观地访问队列,同时防止编译器优化队列轮询,以便代码在队列为空时跳入紧密的 label: goto label;
循环。
警告信息有点误导。 ISO C 不仅禁止
将非标量转换为同一类型;它禁止投射非标量
到或从 any 类型。强制转换运算符的操作数和
强制转换本身指定的类型,必须是标量类型(要么
算术或指针)。
这有一个例外,但不适用于此处。如果
目标类型为void,操作数可以是任意类型
已发布的 struct foo 定义还声明了名为 'bar' 的结构实例。
然后在代码中声明了该结构的第二个实例,名称也是 'bar'。
第二个 'bar' 正在跟踪第一个实例。
仅此一项就会导致编译器发出警告。
这是正确的用法(仍然存在阴影问题)
struct Foo {
int dummy;
} bar;
int main(void)
{
/* This statement causes GCC to produce the warning:
* ISO C forbids casting nonscalar to the same type */
volatile struct Foo bar;
/* The warning may be silenced like so.
* Is this form superior or just trickier? Why? */
//*(volatile struct Foo *)&bar;
return 0;
}
注意,不是试图将 struct Foo 重新定义为 volatile,而是将局部变量 'bar' 声明为 volatile
struct Foo {
int dummy;
} bar;
int main(void)
{
/* This statement causes GCC to produce the warning:
* ISO C forbids casting nonscalar to the same type */
(volatile struct Foo)bar;
/* The warning may be silenced like so.
* Is this form superior or just trickier? Why? */
*(volatile struct Foo *)&bar;
return 0;
}
compiler/standard要防的是什么邪?
背景故事:
有问题的真正代码是使用 ISR 和后台共享的循环 buffer/queue。后台代码不断轮询队列。我希望避免悲观地访问队列,同时防止编译器优化队列轮询,以便代码在队列为空时跳入紧密的 label: goto label;
循环。
警告信息有点误导。 ISO C 不仅禁止 将非标量转换为同一类型;它禁止投射非标量 到或从 any 类型。强制转换运算符的操作数和 强制转换本身指定的类型,必须是标量类型(要么 算术或指针)。
这有一个例外,但不适用于此处。如果 目标类型为void,操作数可以是任意类型
已发布的 struct foo 定义还声明了名为 'bar' 的结构实例。
然后在代码中声明了该结构的第二个实例,名称也是 'bar'。
第二个 'bar' 正在跟踪第一个实例。
仅此一项就会导致编译器发出警告。
这是正确的用法(仍然存在阴影问题)
struct Foo {
int dummy;
} bar;
int main(void)
{
/* This statement causes GCC to produce the warning:
* ISO C forbids casting nonscalar to the same type */
volatile struct Foo bar;
/* The warning may be silenced like so.
* Is this form superior or just trickier? Why? */
//*(volatile struct Foo *)&bar;
return 0;
}
注意,不是试图将 struct Foo 重新定义为 volatile,而是将局部变量 'bar' 声明为 volatile