[Development] QList

Thiago Macieira thiago.macieira at intel.com
Fri Mar 24 16:50:06 CET 2017


Em sexta-feira, 24 de março de 2017, às 05:31:32 PDT, Marc Mutz escreveu:
> Well, where should I start? There are two principles that interact to cause
> all kinds of mayhem, both of them on Windows:
> 
> 1. When a class is exported, all of its members are exported. That includes
>    the base class' members, regsardless of whether they were exported
>    themselves or not.
> 2. When an inline function is exported (by itself or via a class-level
>    export), MSVC calls the copy in the DLL. I don't know whether it places a
> copy in the user's executable at all. You can prevent this behaviour by
> marking each such function with Q_ALWAYS_INLINE.

Note: you may force a local copy with Q_ALWAYS_INLINE, but that does not stop 
the DLL from exporting the function in the first place.

> (2) means we can't change signatures of exported inline functions, because
> that would be BiC on Windows/Debug. On all other platforms, incl.
> Windows/Release, renaming, removing, changing the signature of, an inline
> function, exported or not, is always BC. It may be SiC, but it's always BC.

That still has exceptions, like inlines that have statics inside or if the 
address of the inline is taken. So we should still apply regular our rules for 
BC to those inline functions, with the extra requirement that "it must be ok 
for old code to call the old version". So inlines are actually harder on BC 
than non-inlines...

> We have many use-cases that assume that inline functions do not form part of
> the ABI:
> 
> a. QVector and other container change the signature of begin() etc to
>    implement QT_STRICT_ITERATORS. As a consequence, QT_STRICT_ITERATORS
> fails for (at least) QXmlStreamAttributes, inheriting QVector, because only
> one of the two overloaded functions gets exported while the other one is
> not.
> 
> You may disregard this as a container-only thing, but it's far more
> widespread:
> 
> b. We also assume we can #if Q_COMPILER away functions as long as they are
>    inline. You see where this is going? Once MS actually keeps BC
> themselves, and afaiu, they plan to do so for 2015 -> 2017, this will cause
> BiC in all exported classes whenever 2015 lacks a feature that 2017
> provides.
> 
> I don't know why Thiago thinks these reasons are not worth stopping
> exporting non-polymorphic classes for, but I'm absolutely convinced that
> exporting only non-inline functions in such classes is the only correct way
> to deal with the Microsoft platform.

Because (1) was very restricted and (2) hadn't happened until now. You're 
probably right: all the constexpr (thus inline) functions in our exported 
classes are not present in the MSVC 2015 binaries. So if you compile against 
MSVC 2017, the compiler will expect them to be there and the link will fail. 
We need to verify this is the case.

There's an easy way out: provide an MSVC 2017 binary, so people don't try to 
mix.

We need to reevaluate what to do. I still think the export-each-function-in-
the-class is mighty ugly and should be avoided.

> Non-polymophic classes should decide what they want to be:
> 
> I. if they want to be pimpl'ed, they should have most functions out-of-line.
> In this case, it's ok to export the whole class, but all inline functions
> should have to be marked as Q_ALWAYS_INLINE from the outset.

I disagree with that on style purposes and in the causing of inlining when the 
compiler didn't really want it (even in release mode). But as I said above: 
need reevaluation.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center




More information about the Development mailing list