Re: [Interest] Is it safe to call qRegisterMetaType() before main()?

2019-08-02 Thread Giuseppe D'Angelo via Interest

Il 31/07/19 23:22, Nikos Chantziaras ha scritto:


static void constructor() __attribute__((constructor));
static void constructor(){
     qmlRegisterType("ClassName", 1, 0, "ClassName");
}

Maybe it helps.

Thanks! I didn't know about that one.


You can do that in pure C++, by the way; just define a global object.

--
Giuseppe D'Angelo | giuseppe.dang...@kdab.com | Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com
KDAB - The Qt, C++ and OpenGL Experts



smime.p7s
Description: Firma crittografica S/MIME
___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest


Re: [Interest] Is it safe to call qRegisterMetaType() before main()?

2019-08-02 Thread Nikos Chantziaras

(CC'ing the list as it might be of interest.)

I didn't think volatile would affect the linker. That might indeed work 
if the llvm people think so. I'll try and run some tests when I get to it.


Thanks!


On 02/08/2019 09:54, Dmitriy Purgin wrote:

Oh, thanks, I didn't get it from the beginning.

I saw another trick in clang-tidy which apparently does the same thing: 
declare a volatile variable in global context. See 
https://github.com/llvm-mirror/clang-tools-extra/blob/master/clang-tidy/llvm/LLVMTidyModule.cpp#L41-L43 



Cheers
Dmitriy

On Fri, Aug 2, 2019 at 8:40 AM Nikos Chantziaras > wrote:


The issue that started the whole discussion is that this sometimes
doesn't work when linking statically. The linker might remove
unreferenced global objects if you build your common code into a static
library that you then link into each application. Example:


https://stackoverflow.com/questions/806348/prevent-linker-from-removing-globals

  From what I can tell, __attribute__((constructor)) won't let that
happen.


On 02/08/2019 09:32, Dmitriy Purgin wrote:
 > Hey Nikos,
 >
 > as you noticed, the macro expands to a global static object which is
 > instantiated automatically at program start, thus making it the
same as
 > __attribute__((constructor)) but more portable since it also
works on
 > non-GCC compilers
 >
 > Cheers
 > Dmitriy
 >
 > On Fri, Aug 2, 2019 at 2:24 AM Nikos Chantziaras
mailto:rea...@gmail.com>
 > >> wrote:
 >
 >     That macro defines a global object in an unnamed namespace.
 >     Q_CONSTRUCTOR_FUNCTION(my_function) simply becomes:
 >
 >           namespace {
 >           static const struct my_function_ctor_class_ {
 >               inline my_function_ctor_class_()
 >               {
 >                   my_function();
 >               }
 >           } my_function_ctor_instance_;
 >           }
 >
 >     So it doesn't apply any special attributes to the function.
 >
 >
 >     On 01/08/2019 12:18, Dmitriy Purgin wrote:
 >      > You could also use Q_CONSTRUCTOR_FUNCTION which is
probably more
 >     portable
 >      >
 >      > Cheers
 >      > Dmitriy
 >      >
 >      > On Wed, Jul 31, 2019 at 11:23 PM Nikos Chantziaras
 >     mailto:rea...@gmail.com>
>
 >      > 
      >
 >      >     On 29/07/2019 23:50, Tomas Konir wrote:
 >      >      > I'm using C constructor attribute with no problems.
 >      >      > Code like below at each class cpp file.
 >      >      >
 >      >      > static void constructor() __attribute__((constructor));
 >      >      > static void constructor(){
 >      >      >     qmlRegisterType("ClassName", 1, 0,
 >     "ClassName");
 >      >      > }
 >      >      >
 >      >      > Maybe it helps.
 >      >
 >      >     Thanks! I didn't know about that one.
 >



___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest


Re: [Interest] Is it safe to call qRegisterMetaType() before main()?

2019-07-31 Thread Nikos Chantziaras

On 29/07/2019 23:50, Tomas Konir wrote:

I'm using C constructor attribute with no problems.
Code like below at each class cpp file.

static void constructor() __attribute__((constructor));
static void constructor(){
    qmlRegisterType("ClassName", 1, 0, "ClassName");
}

Maybe it helps.


Thanks! I didn't know about that one.
___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest


Re: [Interest] Is it safe to call qRegisterMetaType() before main()?

2019-07-29 Thread Thiago Macieira
On Monday, 29 July 2019 13:28:04 PDT Nikos Chantziaras wrote:
> > This is only required when referring to it by name, such as in old-style
> > signal-slot connection, QML, D-Bus, etc.
> 
> They're new-style connections, but are sometimes of QueuedConnection
> type since some connections are used for inter-thread communication. If
> I don't use Q_ENUM or Q_REGISTER_METATYPE (and thus also don't call
> qRegisterMetatype(),) the connections won't work and you get this at
> runtime:
> 
>QObject::connect: Cannot queue arguments of type 'MyClass::MyEnum'

The queuing is actually "old style" since it goes back to the meta object 
string format to get the parameter types.

Olivier, didn't you have at some point a patch that made the meta object 
register all parameters as metatypes on request? That would solve Nikos's 
problem.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel System Software Products



___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest


Re: [Interest] Is it safe to call qRegisterMetaType() before main()?

2019-07-29 Thread Thiago Macieira
On Monday, 29 July 2019 09:25:04 PDT Tomasz Olszak wrote:
> What's is the cons of putting something like that in anonymous namespace
> instead of constructor?

It's run on program load, before main(), even if the type is never used.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel System Software Products



___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest


Re: [Interest] Is it safe to call qRegisterMetaType() before main()?

2019-07-29 Thread Tomas Konir
po 29. 7. 2019 v 21:00 odesílatel Nikos Chantziaras 
napsal:

> The linker might remove it from the executable when linking statically,
> because 'registerHelper' is not referenced anywhere.
>
>
> On 29/07/2019 19:25, Tomasz Olszak wrote:
> > What's is the cons of putting something like that in anonymous namespace
> > instead of constructor?
> >
> > namespace {
> > struct RegisterHelper
> > {
> >  RegisterHelper()
> >  {
> >  qRegisterMetaType();
> >  qRegisterMetaType();
> >  qRegisterMetaTypeStreamOperators();
> >  }
> > };
> > static RegisterHelper registerHelper;
> > }
>

Hi,

I'm using C constructor attribute with no problems.
Code like below at each class cpp file.

static void constructor() __attribute__((constructor));




static void constructor(){




   qmlRegisterType("ClassName", 1, 0, "ClassName");




}

Maybe it helps.

Tom

-- 
Tomas Konir
Czech Republic
___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest


Re: [Interest] Is it safe to call qRegisterMetaType() before main()?

2019-07-29 Thread Nikos Chantziaras

On 28/07/2019 07:15, Thiago Macieira wrote:

On Friday, 26 July 2019 17:35:03 PDT Nikos Chantziaras wrote:

I didn't (although I use Q_ENUM, but it does the same job.) But there's
no constructor to put qRegisterMetaType() in. It's an enum. There's no
constructor. Some enums are in a namespace, some are in a class, but
even with an enum that is in a class, users of can just use the enum in
their own signals/slots prior to instantiating the class that declares
the enum. It will stay unregistered until the first instance of the
class is created.



I meant in the class it's most likely to be used in.


Well, putting it in the class it's most likely to be used in is not good 
enough, because this results in "it most likely has been registered, but 
maybe not." To be sure it's registered, you'd have to register it in 
*every* class it's used in. What if you forget? It doesn't scale. Too 
error prone. It's much (much!) better to be in a situation where only 
two cases are possible: it's either *always* registered, or it's *never* 
registered. There should be no middle-ground.


In case of enums, if the enum is in "globals.h", then "globals.cpp" 
should be responsible for registering it. Since global initializers can 
be removed by the linker as they're not referenced in the executable, 
then I'll just have to provide initialization functions and call them in 
main(). That way the qRegisterMetatype() calls stay within the source 
file of the "owner" of the type, and forgetting to register newly added 
types is less likely.




This is only required when referring to it by name, such as in old-style
signal-slot connection, QML, D-Bus, etc.


They're new-style connections, but are sometimes of QueuedConnection 
type since some connections are used for inter-thread communication. If 
I don't use Q_ENUM or Q_REGISTER_METATYPE (and thus also don't call 
qRegisterMetatype(),) the connections won't work and you get this at 
runtime:


  QObject::connect: Cannot queue arguments of type 'MyClass::MyEnum'



Loading it into a QVariant automatically registers, as QVariant calls
qMetaTypeId() to get the metatype ID.


Not sure what you mean here. I'm not using a QVariant anywhere, at least 
not explicitly.

___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest


Re: [Interest] Is it safe to call qRegisterMetaType() before main()?

2019-07-29 Thread Nikos Chantziaras
The linker might remove it from the executable when linking statically, 
because 'registerHelper' is not referenced anywhere.



On 29/07/2019 19:25, Tomasz Olszak wrote:
What's is the cons of putting something like that in anonymous namespace 
instead of constructor?


namespace {
struct RegisterHelper
{
     RegisterHelper()
     {
         qRegisterMetaType();
         qRegisterMetaType();
         qRegisterMetaTypeStreamOperators();
     }
};
static RegisterHelper registerHelper;
}


niedz., 28 lip 2019 o 06:22 Thiago Macieira > napisał(a):


On Friday, 26 July 2019 17:35:03 PDT Nikos Chantziaras wrote:
 > I didn't (although I use Q_ENUM, but it does the same job.) But
there's
 > no constructor to put qRegisterMetaType() in. It's an enum.
There's no
 > constructor. Some enums are in a namespace, some are in a class, but
 > even with an enum that is in a class, users of can just use the
enum in
 > their own signals/slots prior to instantiating the class that
declares
 > the enum. It will stay unregistered until the first instance of the
 > class is created.
 > 

I meant in the class it's most likely to be used in.

This is only required when referring to it by name, such as in
old-style
signal-slot connection, QML, D-Bus, etc.

Loading it into a QVariant automatically registers, as QVariant calls
qMetaTypeId() to get the metatype ID.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com 

   Software Architect - Intel System Software Products



___
Interest mailing list
Interest@qt-project.org 
https://lists.qt-project.org/listinfo/interest


___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest




___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest


Re: [Interest] Is it safe to call qRegisterMetaType() before main()?

2019-07-29 Thread Tomasz Olszak
What's is the cons of putting something like that in anonymous namespace
instead of constructor?

namespace {
struct RegisterHelper
{
RegisterHelper()
{
qRegisterMetaType();
qRegisterMetaType();
qRegisterMetaTypeStreamOperators();
}
};
static RegisterHelper registerHelper;
}


niedz., 28 lip 2019 o 06:22 Thiago Macieira 
napisał(a):

> On Friday, 26 July 2019 17:35:03 PDT Nikos Chantziaras wrote:
> > I didn't (although I use Q_ENUM, but it does the same job.) But there's
> > no constructor to put qRegisterMetaType() in. It's an enum. There's no
> > constructor. Some enums are in a namespace, some are in a class, but
> > even with an enum that is in a class, users of can just use the enum in
> > their own signals/slots prior to instantiating the class that declares
> > the enum. It will stay unregistered until the first instance of the
> > class is created.
> > 
>
> I meant in the class it's most likely to be used in.
>
> This is only required when referring to it by name, such as in old-style
> signal-slot connection, QML, D-Bus, etc.
>
> Loading it into a QVariant automatically registers, as QVariant calls
> qMetaTypeId() to get the metatype ID.
>
> --
> Thiago Macieira - thiago.macieira (AT) intel.com
>   Software Architect - Intel System Software Products
>
>
>
> ___
> Interest mailing list
> Interest@qt-project.org
> https://lists.qt-project.org/listinfo/interest
>
___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest


Re: [Interest] Is it safe to call qRegisterMetaType() before main()?

2019-07-27 Thread Thiago Macieira
On Friday, 26 July 2019 17:35:03 PDT Nikos Chantziaras wrote:
> I didn't (although I use Q_ENUM, but it does the same job.) But there's
> no constructor to put qRegisterMetaType() in. It's an enum. There's no
> constructor. Some enums are in a namespace, some are in a class, but
> even with an enum that is in a class, users of can just use the enum in
> their own signals/slots prior to instantiating the class that declares
> the enum. It will stay unregistered until the first instance of the
> class is created.
> 

I meant in the class it's most likely to be used in.

This is only required when referring to it by name, such as in old-style 
signal-slot connection, QML, D-Bus, etc.

Loading it into a QVariant automatically registers, as QVariant calls 
qMetaTypeId() to get the metatype ID.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel System Software Products



___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest


Re: [Interest] Is it safe to call qRegisterMetaType() before main()?

2019-07-26 Thread Nikos Chantziaras

On 25/07/2019 06:20, Thiago Macieira wrote:

On Wednesday, 24 July 2019 09:05:02 PDT Nikos Chantziaras wrote:

On 24/07/2019 17:23, Thiago Macieira wrote:

On Tuesday, 23 July 2019 07:27:27 PDT Nikos Chantziaras wrote:

Ugh. Having the call happen on every object creation sounds even uglier.
It seems it's best to roll our own. Probably a lazily initialized global
static object that you can add functors to before main() and then run
all functors of that object in main().


Use qMetaTypeId(). That will include an inline check (runtime, sure)
whether it's already been registered.


That is a good solution for instantiable types, but for enums (my actual
use case) you can't do that.


Why not? Did you forget the Q_DECLARE_METATYPE?


I didn't (although I use Q_ENUM, but it does the same job.) But there's 
no constructor to put qRegisterMetaType() in. It's an enum. There's no 
constructor. Some enums are in a namespace, some are in a class, but 
even with an enum that is in a class, users of can just use the enum in 
their own signals/slots prior to instantiating the class that declares 
the enum. It will stay unregistered until the first instance of the 
class is created.

___
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest