为什么 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