Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. static const QString, implicit sharing issue
Forum Updated to NodeBB v4.3 + New Features

static const QString, implicit sharing issue

Scheduled Pinned Locked Moved Solved General and Desktop
14 Posts 4 Posters 5.1k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    J.Hilk
    Moderators
    wrote on 20 Dec 2018, 10:18 last edited by
    #1

    Hi,

    I have a very stange bug I would like to understand more about,

    Qt Version 5.11.2 (can't upgrade to 5.12 unfortunately because it does not happen with 5.12)
    Target OS android.

    I have a header file that contains a bunch of const static QStrings that are used throught the application.

    In my App I have the following line of code:

    QString DefaultPath(dataPath );
    

    where dataPath is the static const QString, this line crashes.

    However when I do the following

    QString DefaultPath(dataPath + "" );
    

    basically forcing a copy, it does not crash.
    It also only crashes on my Samsung device, the HUAWEI one works fine.
    Also also it only crashes in release mode, debug works fine acrosss the board.

    I know how to fix this, but I would like to know more about what is going on here.

    Anyone any idea?


    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


    Q: What's that?
    A: It's blue light.
    Q: What does it do?
    A: It turns blue.

    1 Reply Last reply
    1
    • C Online
      C Online
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on 20 Dec 2018, 10:47 last edited by
      #2

      @J.Hilk said in static const QString, implicit sharing issue:

      dataPath

      Is it a QStringLiteral ?

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      J 1 Reply Last reply 20 Dec 2018, 10:53
      0
      • C Christian Ehrlicher
        20 Dec 2018, 10:47

        @J.Hilk said in static const QString, implicit sharing issue:

        dataPath

        Is it a QStringLiteral ?

        J Offline
        J Offline
        J.Hilk
        Moderators
        wrote on 20 Dec 2018, 10:53 last edited by
        #3

        @Christian-Ehrlicher
        no

        static const QString defaultPath    = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/MPR/");
        static const QString dataPath       = defaultPath + QString("Data/");
        

        should it be?


        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


        Q: What's that?
        A: It's blue light.
        Q: What does it do?
        A: It turns blue.

        1 Reply Last reply
        0
        • C Online
          C Online
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on 20 Dec 2018, 11:27 last edited by
          #4

          No, it was just a guess since there are known issues with QStringLiteral in a plugin when the plugin gets unloaded.
          Do you get a useful backtrace? I would maybe change it to

          static QString defaultPath() { return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/MPR/"); }

          To avoid global statics.

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          J 1 Reply Last reply 20 Dec 2018, 11:45
          3
          • C Christian Ehrlicher
            20 Dec 2018, 11:27

            No, it was just a guess since there are known issues with QStringLiteral in a plugin when the plugin gets unloaded.
            Do you get a useful backtrace? I would maybe change it to

            static QString defaultPath() { return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/MPR/"); }

            To avoid global statics.

            J Offline
            J Offline
            J.Hilk
            Moderators
            wrote on 20 Dec 2018, 11:45 last edited by
            #5

            @Christian-Ehrlicher well, that fixes the issue as well, and is probably the more reasonable fix, than adding an empty QString to dataPath when I use it.

            Lot's of refactoring to do! x)

            Thanks.


            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            A 1 Reply Last reply 20 Dec 2018, 11:58
            0
            • J J.Hilk
              20 Dec 2018, 11:45

              @Christian-Ehrlicher well, that fixes the issue as well, and is probably the more reasonable fix, than adding an empty QString to dataPath when I use it.

              Lot's of refactoring to do! x)

              Thanks.

              A Offline
              A Offline
              aha_1980
              Lifetime Qt Champion
              wrote on 20 Dec 2018, 11:58 last edited by
              #6

              @J.Hilk

              And it is the only feasible solution. Having non-POD-types as global variables is undefined behavior, as the constructor of your global static might be run anytime (and you don't know when). Therefore its eays to access the data before it is initialized.

              Regards

              Qt has to stay free or it will die.

              J 1 Reply Last reply 20 Dec 2018, 12:11
              0
              • A aha_1980
                20 Dec 2018, 11:58

                @J.Hilk

                And it is the only feasible solution. Having non-POD-types as global variables is undefined behavior, as the constructor of your global static might be run anytime (and you don't know when). Therefore its eays to access the data before it is initialized.

                Regards

                J Offline
                J Offline
                J.Hilk
                Moderators
                wrote on 20 Dec 2018, 12:11 last edited by
                #7

                @aha_1980
                well technically, the only non POD-qualifying trait would be QString not being an intrinsic type - which is enough ;-). Never the less your argument still holds true!


                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                Q: What's that?
                A: It's blue light.
                Q: What does it do?
                A: It turns blue.

                kshegunovK 1 Reply Last reply 20 Dec 2018, 20:13
                0
                • J J.Hilk
                  20 Dec 2018, 12:11

                  @aha_1980
                  well technically, the only non POD-qualifying trait would be QString not being an intrinsic type - which is enough ;-). Never the less your argument still holds true!

                  kshegunovK Offline
                  kshegunovK Offline
                  kshegunov
                  Moderators
                  wrote on 20 Dec 2018, 20:13 last edited by
                  #8

                  Actually I'm pretty sure the problem is not so much it being POD or not, but rather that you have dependent initialization.
                  dataPath depends on defaultPath but C++ does not guarantee you order of initialization of statics. So dataPath might just be initialized with garbage (i.e. before defaultPath is initialized). Additionally, I think QStandardPaths (I may think wrong) is available only after QCoreApplication is up and running.

                  Read and abide by the Qt Code of Conduct

                  kshegunovK J 2 Replies Last reply 21 Dec 2018, 06:26
                  4
                  • kshegunovK kshegunov
                    20 Dec 2018, 20:13

                    Actually I'm pretty sure the problem is not so much it being POD or not, but rather that you have dependent initialization.
                    dataPath depends on defaultPath but C++ does not guarantee you order of initialization of statics. So dataPath might just be initialized with garbage (i.e. before defaultPath is initialized). Additionally, I think QStandardPaths (I may think wrong) is available only after QCoreApplication is up and running.

                    kshegunovK Offline
                    kshegunovK Offline
                    kshegunov
                    Moderators
                    wrote on 21 Dec 2018, 06:26 last edited by kshegunov
                    #9

                    @J-Hilk, could you try something for me btw, just out of curiosity:

                    static struct  {
                        const QString defaultPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/MPR/");
                        const QString dataPath = defaultPath + QString("Data/");
                    } strings;
                    

                    Does that have the same problem?

                    Read and abide by the Qt Code of Conduct

                    J 1 Reply Last reply 21 Dec 2018, 06:37
                    1
                    • kshegunovK kshegunov
                      20 Dec 2018, 20:13

                      Actually I'm pretty sure the problem is not so much it being POD or not, but rather that you have dependent initialization.
                      dataPath depends on defaultPath but C++ does not guarantee you order of initialization of statics. So dataPath might just be initialized with garbage (i.e. before defaultPath is initialized). Additionally, I think QStandardPaths (I may think wrong) is available only after QCoreApplication is up and running.

                      J Offline
                      J Offline
                      J.Hilk
                      Moderators
                      wrote on 21 Dec 2018, 06:27 last edited by J.Hilk
                      #10

                      @kshegunov very true,

                      It's probably for the best, if I'll wrap this all in a propper class at this point.
                      I centralized all those path for 2 reasons.

                      • I had to change 1 path and boy, was that a pain.
                      • I wanted to reduze the overall memory consumption of the app.
                      1. Still applies,
                      2. doesn't matter if it's not static but constructed at runtime.

                      legacy code - there's always something x)


                      Does that have the same problem?

                      I'll test it.


                      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                      Q: What's that?
                      A: It's blue light.
                      Q: What does it do?
                      A: It turns blue.

                      1 Reply Last reply
                      1
                      • kshegunovK kshegunov
                        21 Dec 2018, 06:26

                        @J-Hilk, could you try something for me btw, just out of curiosity:

                        static struct  {
                            const QString defaultPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/MPR/");
                            const QString dataPath = defaultPath + QString("Data/");
                        } strings;
                        

                        Does that have the same problem?

                        J Offline
                        J Offline
                        J.Hilk
                        Moderators
                        wrote on 21 Dec 2018, 06:37 last edited by
                        #11

                        @kshegunov said in static const QString, implicit sharing issue:

                        @J-Hilk, could you try something for me btw, just out of curiosity:

                        static struct  {
                            const QString defaultPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/MPR/");
                            const QString dataPath = defaultPath + QString("Data/");
                        } strings;
                        

                        Does that have the same problem?

                        It does not! Works fine with the static struct.


                        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                        Q: What's that?
                        A: It's blue light.
                        Q: What does it do?
                        A: It turns blue.

                        kshegunovK 1 Reply Last reply 21 Dec 2018, 06:40
                        2
                        • J J.Hilk
                          21 Dec 2018, 06:37

                          @kshegunov said in static const QString, implicit sharing issue:

                          @J-Hilk, could you try something for me btw, just out of curiosity:

                          static struct  {
                              const QString defaultPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/MPR/");
                              const QString dataPath = defaultPath + QString("Data/");
                          } strings;
                          

                          Does that have the same problem?

                          It does not! Works fine with the static struct.

                          kshegunovK Offline
                          kshegunovK Offline
                          kshegunov
                          Moderators
                          wrote on 21 Dec 2018, 06:40 last edited by
                          #12

                          Indeed, so you have your answer then. One note: this "hack" is going to work only with dynamic linking. If you go to static you're going to run into the same stuff, and not in a good way ... ;) Static init is per-module, so having only one module means at that struct's init QStandardPaths::writableLocation's statics may just be initialized sometime in the future.

                          Read and abide by the Qt Code of Conduct

                          J 1 Reply Last reply 21 Dec 2018, 06:48
                          1
                          • kshegunovK kshegunov
                            21 Dec 2018, 06:40

                            Indeed, so you have your answer then. One note: this "hack" is going to work only with dynamic linking. If you go to static you're going to run into the same stuff, and not in a good way ... ;) Static init is per-module, so having only one module means at that struct's init QStandardPaths::writableLocation's statics may just be initialized sometime in the future.

                            J Offline
                            J Offline
                            J.Hilk
                            Moderators
                            wrote on 21 Dec 2018, 06:48 last edited by
                            #13

                            @kshegunov I'm learning something new every day :D

                            However, I'll stick to the proper class implementation and inherit from that simple class where the standardpaths are needed. It's the way, where the least refractoring is needed. I'm kind of on a deadline so close to christmas x)

                            Thanks all for bringing light to my dark place, where I spend the last couple of days figuring this out, and I'm cutting it close as it is.


                            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                            Q: What's that?
                            A: It's blue light.
                            Q: What does it do?
                            A: It turns blue.

                            kshegunovK 1 Reply Last reply 21 Dec 2018, 06:51
                            1
                            • J J.Hilk
                              21 Dec 2018, 06:48

                              @kshegunov I'm learning something new every day :D

                              However, I'll stick to the proper class implementation and inherit from that simple class where the standardpaths are needed. It's the way, where the least refractoring is needed. I'm kind of on a deadline so close to christmas x)

                              Thanks all for bringing light to my dark place, where I spend the last couple of days figuring this out, and I'm cutting it close as it is.

                              kshegunovK Offline
                              kshegunovK Offline
                              kshegunov
                              Moderators
                              wrote on 21 Dec 2018, 06:51 last edited by
                              #14

                              @J.Hilk said in static const QString, implicit sharing issue:

                              @kshegunov I'm learning something new every day :D

                              Don't we all ... :)

                              However, I'll stick to the proper class implementation and inherit from that simple class where the standardpaths are needed.

                              Probably the best and most reliable solution.

                              I'm kind of on a deadline so close to christmas x)

                              I hear you brother! I have to deliver on the 2nd of January.

                              Read and abide by the Qt Code of Conduct

                              1 Reply Last reply
                              0

                              1/14

                              20 Dec 2018, 10:18

                              • Login

                              • Login or register to search.
                              1 out of 14
                              • First post
                                1/14
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • Users
                              • Groups
                              • Search
                              • Get Qt Extensions
                              • Unsolved