C 是",;易挥发;继承指针的属性?

C 是",;易挥发;继承指针的属性?,c,pointers,volatile,C,Pointers,Volatile,假设我有以下代码: my_struct_member_type *foo() { volatile my_struct *s = (my_struct *)SOME_ADDRESS; return &(s->struct_member); } foo返回的指针是否也是易变的 编辑:一个后续:指针&(s->struct_member)是否在foo内部易变?否。易变是一个编译器提示,因此只在编译器可以看到它时才受尊重。该函数可以从另一个翻译单元调用,它不知道您最初如何

假设我有以下代码:

my_struct_member_type *foo() {
    volatile my_struct *s = (my_struct *)SOME_ADDRESS;
    return &(s->struct_member);
}
foo返回的指针是否也是易变的


编辑:一个后续:指针
&(s->struct_member)
是否在foo内部易变?

否。
易变
是一个编译器提示,因此只在编译器可以看到它时才受尊重。该函数可以从另一个翻译单元调用,它不知道您最初如何声明指针
volatile

volatile在运行时没有意义,它用于告诉编译器不要优化对变量的访问

返回volatile指针是胡说八道。您将某些存储(左值)标记为volatile,而不是rvalue

是的

对于
volatile,my_struct*s
表示通过它看到的对象是
volatile
,并且通过该指针访问的所有成员都继承
volatile
限定

如果返回类型没有这样说,则返回指向
volatile
的指针的地址是违反约束的,并且您的编译器必须为此向您提供诊断

编辑:对于
volatile
关键字的应用位置似乎也存在混淆。在您的示例中,它应用于指向的对象,而不是指针本身。根据经验,在不更改类型的情况下,始终将限定符(
const
volatile
)写得尽可能靠右。您的示例如下:

my_struct volatile*s = (my_struct *)SOME_ADDRESS;
这完全不同于

my_struct *volatile s = (my_struct *)SOME_ADDRESS;
指针本身是易变的,但不是它后面的对象

编辑2:由于您询问我的来源,实际的C标准C11,6.8.6.4中提到了
return
语句:

如果表达式的类型与 函数中,该值被转换为 赋值给具有函数返回类型的对象

So 6.15.16.1对于赋值运算符,转换的预期结果:

左操作数具有原子指针、限定指针或非限定指针类型, and(考虑左值之后的左操作数的类型) 转换)两个操作数都是合格或不合格的指针 兼容类型的版本,左侧指向的类型 右边所指类型的所有限定符


在这里,右边的指针类型在左边的基础上增加了
volatile
限定符。

我不知道这个问题的答案,但是你读过吗?下面是一个问题:指针和(s->struct_成员)在foo内部是不是volatile?我想,是的,因为,
和(s->struct_成员)==s+offsetof(typeof(s),struct_成员)
我不太确定。。。这是一个新的值。它与s不同,也不是一个变量;据我所知,volatile是variable的属性,而不是value。不过我想确认一下这个理论。
volatile我的_struct*a
意味着只要你通过
a
指针访问它,结构的内容就会被视为volatile。但是做
int*i=&a->member
i
不会被视为易失性。如果要将指针本身标记为volatile,可以执行
my_struct*volatile aint*i=&a->member
是一个违反约束的行为,因此程序的行为是未定义的。很抱歉,您的回答毫无意义。但他并没有返回一个
volatile
指针,而是返回一个指向
volatile
对象的指针,这非常有意义。问题是:“foo返回的指针是否也是易变的?不,指针未声明为volatile。要实现这一点,声明必须阅读
my_struct volatile*volatile s
。指针仅在限定符位于
*
右侧时才受影响。因此,如果我理解正确,如果某个地址的对象通过指针声明声明为volatile,那么它在程序的每个可能范围内都会成为volatile对象?即使是对赋予它volatile属性的指针一无所知的作用域?另外,考虑到我们在这里的答案中看到的分歧,您能提到一些信息来源吗?您必须区分对象本身和访问对象的类型。您只在一个地方声明和定义一个对象,那么它是否易变。如果您通过一个指针访问一个易失性对象,该对象表示它不是易失性的,这就是所谓的未定义行为,即任何可能发生的情况,直到程序崩溃或窃取您的钱。还可以找到此链接,其中包含一些有用的信息: