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.HilkJ Offline
    J.HilkJ Offline
    J.Hilk
    Moderators
    wrote on 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
    • Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on 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.HilkJ 1 Reply Last reply
      0
      • Christian EhrlicherC Christian Ehrlicher

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

        dataPath

        Is it a QStringLiteral ?

        J.HilkJ Offline
        J.HilkJ Offline
        J.Hilk
        Moderators
        wrote on 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
        • Christian EhrlicherC Offline
          Christian EhrlicherC Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on 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.HilkJ 1 Reply Last reply
          3
          • Christian EhrlicherC Christian Ehrlicher

            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.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote on 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.

            aha_1980A 1 Reply Last reply
            0
            • J.HilkJ J.Hilk

              @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.

              aha_1980A Offline
              aha_1980A Offline
              aha_1980
              Lifetime Qt Champion
              wrote on 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.HilkJ 1 Reply Last reply
              0
              • aha_1980A aha_1980

                @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.HilkJ Offline
                J.HilkJ Offline
                J.Hilk
                Moderators
                wrote on 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
                0
                • J.HilkJ J.Hilk

                  @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 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.HilkJ 2 Replies Last reply
                  4
                  • kshegunovK kshegunov

                    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 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.HilkJ 1 Reply Last reply
                    1
                    • kshegunovK kshegunov

                      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.HilkJ Offline
                      J.HilkJ Offline
                      J.Hilk
                      Moderators
                      wrote on 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

                        @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.HilkJ Offline
                        J.HilkJ Offline
                        J.Hilk
                        Moderators
                        wrote on 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
                        2
                        • J.HilkJ J.Hilk

                          @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 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.HilkJ 1 Reply Last reply
                          1
                          • kshegunovK kshegunov

                            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.HilkJ Offline
                            J.HilkJ Offline
                            J.Hilk
                            Moderators
                            wrote on 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
                            1
                            • J.HilkJ J.Hilk

                              @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 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

                              • Login

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