“易失性”有多少次使用? C++ 中有关键字函数,从语法角度?

发布于 2024-12-07 18:57:53 字数 775 浏览 1 评论 0原文

我基于这个概念问这个函数(也许不正确?!):只要可以存在 const 的地方,就可以存在 volatile 的地方。

class classA
{
public:
    const int Foo() const;
}

这里第一个“const”表示返回值是const,我们不能改变它。 第二个const表示“Is Query”,该函数不能改变成员变量,也不能调用非const函数。

现在谈到 volatile:我可以理解 volatile 对变量的作用,例如“volatile int a;” 但是我不知道以下之间的区别:

Case 1: The return type is volatile?
volatile void Function1();

Case 2: The function can only call volatile functions? Why add volatile here? Any example?
void Function2() volatile;

Case 3:   Is it valid? If yes, is it simply a combination of Case 1 and Case 2?
volatile void Function3() volatile;

当我们将 const 放在函数声明的末尾时,它有一个漂亮的名字:“Is Query” 你能为案例 2 中的“易失性”起一个合适的名称/别名吗? 我的意思是,每当我们称呼这个名字时,我们就知道我们正在谈论案例 2,而不是案例 1。

提前谢谢您!

I asked this function based on this concept (maybe incorrect?!): Wherever a const can exist, a volatile can exist at the place.

class classA
{
public:
    const int Foo() const;
}

Here the first "const" means the return value is const, we can not change it.
the second const means "Is Query", this function can not change the member variable and can not call non-const function.

Now comes to volatile: I can understand what volatile does on a variable, like "volatile int a;"
However I have no idea of the difference among the following:

Case 1: The return type is volatile?
volatile void Function1();

Case 2: The function can only call volatile functions? Why add volatile here? Any example?
void Function2() volatile;

Case 3:   Is it valid? If yes, is it simply a combination of Case 1 and Case 2?
volatile void Function3() volatile;

When we put the const at the end of function declaration, it has a beautiful name: "Is Query"
Can you give a decent name/alias to the "volatile" in Case 2?
I mean, whenever we call this name, we can know we are talking about Case 2, not case 1.

Thank you in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

等你爱我 2024-12-14 18:57:53

易失性有一个主要功能,也就是说“停止!该对象连接到外部资源,因此当我写入它时,不要相对于其他易失性读取或写入重新排序写入,并且当我读取它时,不要同样重新排序,也不要优化它们!”。

为了支持这一点,您可以在成员函数之后放置 易失性,这是调用 易失性 类对象上的成员函数所必需的。

// just a silly example
struct HWOverlayClock {
  HWOverlayClock() { }

  int64_t getTime() volatile const { return timestamp; }

  int64_t timestamp;
};

// imagine we use an implementation defined way to put the
// object at some fixed machine address
volatile const HWOverlayClock clock __attribute__((at_address(0xbabe)));

易失性 放在返回值上也可以完成,但在我看来,它的用处不大,因为返回值通常是临时的,并且 易失性 语义非常重要。临时规模相反。将 易失性 放在 void 上是特别无意义的(如果将 const易失性 放在 a 的顶层,则会被忽略。如果类型不是类类型,则返回类型(即,如果它是指针,则位于 * 的右侧),因为这些返回值与内存不对应,也可能由实现保存在寄存器中)。将 易失性 放在非顶级引用或指针可能会很有用,如下所示

struct Controller {
    HWOverlayClock volatile const* getClock() const { return clock; }

private:
    volatile const HWOverlayClock *clock;
};

希望它有所帮助。

Volatile has one primary function, which is to say "STOP! This object is connected to external resources, and thus when I write to it, don't reorder the write with respect to other volatile reads or writes, and when I read to it, don't reorder it likewise and don't optimize these away!".

To support this, you can put volatile after member functions, which is necessary to call member functions on volatile class objects.

// just a silly example
struct HWOverlayClock {
  HWOverlayClock() { }

  int64_t getTime() volatile const { return timestamp; }

  int64_t timestamp;
};

// imagine we use an implementation defined way to put the
// object at some fixed machine address
volatile const HWOverlayClock clock __attribute__((at_address(0xbabe)));

Putting volatile on a return value can be done too, but it seems to me that it would be less useful since return values are usually temporaries and volatile semantics are quite on the the opposite scale of temporaries. Putting volatile on void is particularly nonsensical (const and volatile are ignored if put at the top-level of a return type if the type is not a class type (i.e at the right of a * if it is a pointer), because these return values do not correspond to memory, likely being kept in registers by implementations too). Putting volatile on non-toplevel for references or pointers can be useful, like in the following

struct Controller {
    HWOverlayClock volatile const* getClock() const { return clock; }

private:
    volatile const HWOverlayClock *clock;
};

Hope it helps.

书间行客 2024-12-14 18:57:53

第二个const表示“当this是指向const的指针时可以使用”,该函数不能改变非- this可变成员变量且不能调用this上的非常量函数>.

在那里,为你解决了这个问题。

现在应该清楚 volatile 成员函数的含义了:当 this 是指向 volatile 的指针时可以调用它。要求它只能调用其他成员函数(如果它们也是易失性的)是一个结果,但不是核心含义。

the second const means "can be used when this is a pointer to const", this function can not change non-mutable member variables of this and can not call non-const functions on this.

There, fixed that for you.

Now it should be clear what a volatile member function means: it can be called when this is a pointer to volatile. The requirement that it can only call other member functions if they also are volatile is a consequence, but not the core meaning.

旧人哭 2024-12-14 18:57:53

第二个const表示“Is Query”,该函数不能改变成员变量,也不能调用非const函数。

是的,没错。

易失性无效函数1();
返回类型是易失性的?

这里函数的返回类型是void(没有任何意义)。如果它不返回任何内容,则指定返回的内容为易失性是没有意义的。前面的 void 将是多余的。

如果返回类型是 int,那么它前面的 volatile 就适用于返回类型。这意味着该返回值只能采用易失性变量类型。

void Function2() 易失性;
函数只能调用易失性函数吗?为什么要在这里添加 volatile 呢?有什么例子吗?

是的,没错。请参阅下面的代码示例来演示这一点。

易失性无效Function3()易失性;
有效吗?如果是,是否只是情况 1 和情况 2 的组合?

情况1中的易失性是多余的,如果函数返回void(无),则返回值是易失性是没有意义的,所以上面基本上相当于情况 2。

示例示例

#include<iostream>

class Myclass
{
    public:
        volatile int i;
        Myclass():i(10){} 
        void doSomething()
        {
            std::cout<<"\nInside doSomething";
        }
        void doSomethingMore() volatile
        {
            std::cout<<"\nInside doSomethingMore";
            doSomething();   //Error


        }

};

int main()
{
     Myclass obj;
     obj.doSomethingMore();

     return 0;
}

“Is Query”你能给案例2中的“易失性”一个合适的名称/别名吗?我的意思是,每当我们调用这个名字时,我们就可以知道我们正在谈论案例 2,而不是案例 1。

遵循简单的规则:
每当声明或定义中的函数签名末尾出现 volatileconst 关键字时,该关键字就适用于该函数。

这是因为函数签名之前的任何内容都适用于返回类型。

在函数签名之前使用 volatile 关键字更有意义,因为它准确地表明了目的,我认为您应该坚持这种标准方式,因为它比任何别名都更清楚地表明了意图。

The second const means "Is Query", this function can not change the member variable and can not call non-const function.

Yes, thats correct.

volatile void Function1();
The return type is volatile?

The return type of the function here is void(means nothing). If it returns nothing, it makes no sense to specify that the nothing being returned be volatile. The volatile preceeding void will be reduntant.

If the return type was int, then yes the volatile preceeding it applies to the return type. It means that this return value can only be taken in a variable type which is volatile.

void Function2() volatile;
The function can only call volatile functions? Why add volatile here? Any example?

Yes, thats correct. See the Code Example below which demonstrates this.

volatile void Function3() volatile;
Is it valid? If yes, is it simply a combination of Case 1 and Case 2?

The volatile in Case 1, is redundant, If a function is returning void(nothing) it makes no sense that the returned value be volatile, So essentially above is equivalent to just case 2.

An sample Example:

#include<iostream>

class Myclass
{
    public:
        volatile int i;
        Myclass():i(10){} 
        void doSomething()
        {
            std::cout<<"\nInside doSomething";
        }
        void doSomethingMore() volatile
        {
            std::cout<<"\nInside doSomethingMore";
            doSomething();   //Error


        }

};

int main()
{
     Myclass obj;
     obj.doSomethingMore();

     return 0;
}

"Is Query" Can you give a decent name/alias to the "volatile" in Case 2? I mean, whenever we call this name, we can know we are talking about Case 2, not case 1.

Follow the simple rule:
Whenever the volatile or the const keywords appear at the end of the function signature in declaration or definition the keyword applies to the function.

This is because anything that preceeds the function signature applies to the return type.

It make more sense to use the volatile keyword preeceding the function signature because it exactly indicates the purpose, I think you should stick to this standard way because it demonstrates the intent more clearly than any alias would.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文