代码之家  ›  专栏  ›  技术社区  ›  Bri Bri

在C++中,当表达式涉及某个对象时,将表达式赋给该对象时,是否有定义的操作顺序?

  •  3
  • Bri Bri  · 技术社区  · 7 年前

    QMap :

    #include <QMap>
    #include <iostream>
    
    QMap<int, int> myMap;
    
    int count() {
        return myMap.size();
    }
    
    int main() {
        myMap[0] = count();
        std::cout << myMap[0] << std::endl;
        return 0;
    }
    

    取决于是否 myMap count() 执行时,此代码的输出将为 1 0 分别地

    QMap ? 或者C++规范是否保证何时 计数() QMap::operator[] ? 或者结果是不确定的,这是最好避免的情况吗?

    我问这个问题是因为我在一个正在开发的程序中遇到了一个基本相同的情况。当我在Windows中编译这个程序并使用Qt5.5.1 DLL运行它时,结果是 0 1.

    我希望我能理解同一个程序是如何有两种不同的行为的,这样我将来就可以避免这样的错误。

    3 回复  |  直到 7 年前
        1
  •  6
  •   user2371524 user2371524    7 年前

    您的问题:

    myMap[0] = count();
    

    整个作业是一个 以及对 count() 是一个 .没有

    这不是关于 评估顺序 .任务具有 副作用 QMap .仅在 ,你可以保证 副作用 源于 序列点 已完成。

    一个序列点,但它位于函数参数的求值和实际调用之间——与返回值无关。因为这里没有任何论点,所以它不适用于这种情况。

    here's a quite exhaustive answer on the topic of sequence points .


    解决方案当然很简单:使用两个单独的语句。陈述的结尾( ;

        2
  •  0
  •   user2100815 user2100815    7 年前

      void f( X a, X b );
    

    其中a或b可以首先评估。

    这不一定特定于特定的编译器-同一编译器可能在不同的情况下选择不同的求值顺序。

        3
  •  0
  •   Alex Huszagh    7 年前

    不幸的是,据我所知,与Python之类的语言不同,对于计算顺序,无论是给定的编译器、编译器版本还是库,都没有定义顺序。您的代码依赖于未定义的行为。

    有一些 rules 然而,编译器必须遵循的:这不是其中之一。他们给出的未定义行为示例与您的示例类似:

    a[i] = i++;