Interesting clang behavior/bug? on Windows

I am compiling code with "-c -x c++ -O0 -g -fno-inline -Wall -g"
using clang targeting mingw/gcc on Windows.

This code compiles with no errors ( boost::scoped_ptr<T> is non-copyable, non-assignable ):

#include <boost/scoped_ptr.hpp>
class
AClass { boost::scoped_ptr<int> sp_pointer; };
int main() { return 0; }

This code compiles with no errors:

#include <boost/scoped_ptr.hpp>
class __attribute__((__visibility__("default")))
AClass { boost::scoped_ptr<int> sp_pointer; };
int main() { return 0; }

but this code compiles with errors:

#include <boost/scoped_ptr.hpp>
class __attribute__((dllexport))
AClass { boost::scoped_ptr<int> sp_pointer; };
int main() { return 0; }

test_clang_bug.cpp:3:1: error: field of type 'boost::scoped_ptr<int>' has private copy constructor
AClass { boost::scoped_ptr<int> sp_pointer; };
^
..\..\..\boost/smart_ptr/scoped_ptr.hpp:47:5: note: declared private here
    scoped_ptr(scoped_ptr const &);
    ^
test_clang_bug.cpp:3:1: note: implicit copy constructor for 'AClass' first required here
AClass { boost::scoped_ptr<int> sp_pointer; };
^
test_clang_bug.cpp:3:1: error: 'operator=' is a private member of 'boost::scoped_ptr<int>'
AClass { boost::scoped_ptr<int> sp_pointer; };
^
..\..\..\boost/smart_ptr/scoped_ptr.hpp:48:18: note: declared private here
    scoped_ptr & operator=(scoped_ptr const &);
                 ^
test_clang_bug.cpp:3:1: note: implicit copy assignment operator for 'AClass' first required here
AClass { boost::scoped_ptr<int> sp_pointer; };
^
2 errors generated.

Comments ?

Should I file a bug report ?

I do not see why, even "exporting" a class, clang should give an error. If I am not copying/assigning an instance of a class I should never get a compiler error telling me that some member is not copyable or assignable.

Hans would know for sure, but I think this is intentional: Since AClass is dllexported, all its implicit functions get generated (so that they can be exported from the dll), which means they need to be semantically checked. If you give the class a deleted copy constructor and assignment operator, it might work.

Hans would know for sure, but I think this is intentional: Since AClass
is dllexported, all its implicit functions get generated (so that they
can be exported from the dll), which means they need to be semantically
checked. If you give the class a deleted copy constructor and assignment
operator, it might work.

Where in the C++ standard is such behavior justified ?

The C++ standard does tell us I believe that if an object of a class is not copied there is never a need to specify a copy constructor and if a class is not assigned there is never a need to specify an assignment operator, whether or not one has a non-copyable or non-assignable member or not. Changing that basic rule to support something in clang related to "exported' classes cannot be correct IMO.

Why does '__attribute__((__visibility__("default")))' work but '__attribute__((dllexport))' does not ? Aren't they both the equivalent of "exporting" a class in clang ?

I realize that for clang on Windows targeting mingw/gcc and not VC++ that the correct "export" attribute is probably '__attribute__((__visibility__("default")))' and not '__attribute__((dllexport))'. But I heavily object to the idea that because I might be exporting a class the rules of copyability or assignability for that class must change contrary to the C++ standard. This also puts an extra conceptual burden on the design of a class.

Hans would know for sure, but I think this is intentional: Since AClass
is dllexported, all its implicit functions get generated (so that they
can be exported from the dll), which means they need to be semantically
checked. If you give the class a deleted copy constructor and assignment
operator, it might work.

Where in the C++ standard is such behavior justified ?

You're using a non-standard feature (dllexport); the C++ standard's
guarantees are not relevant.

The C++ standard does tell us I believe that if an object of a class is not

copied there is never a need to specify a copy constructor and if a class
is not assigned there is never a need to specify an assignment operator,
whether or not one has a non-copyable or non-assignable member or not.
Changing that basic rule to support something in clang related to
"exported' classes cannot be correct IMO.

Why does '__attribute__((__visibility__("default")))' work but
'__attribute__((dllexport))' does not ? Aren't they both the equivalent of
"exporting" a class in clang ?

I realize that for clang on Windows targeting mingw/gcc and not VC++ that
the correct "export" attribute is probably '__attribute__((__visibility__("default")))'
and not '__attribute__((dllexport))'. But I heavily object to the idea that
because I might be exporting a class the rules of copyability or
assignability for that class must change contrary to the C++ standard. This
also puts an extra conceptual burden on the design of a class.

If our behavior doesn't match mingw here, that's probably a bug. IIRC, MS
__declspec(dllexport) has the behavior of triggering the defintiions of all
implicit special member functions, but it's possible that
__attribute__((dllexport)) should not do the same thing.

Hans would know for sure, but I think this is intentional: Since AClass
is dllexported, all its implicit functions get generated (so that they
can be exported from the dll), which means they need to be semantically
checked. If you give the class a deleted copy constructor and assignment
operator, it might work.

Where in the C++ standard is such behavior justified ?

The C++ standard doesn't talk about dllexport, so it won't say either way.

This isn't a question of standards, it's a question of practicality. The
way dllexport / dllimport are used is usually like so (think of a class
that has a valid copy constructor for a bit):

#ifdef IMPL
#define EXPORT __attribute__((dllexport))
#else
#define EXPORT __attribute((dllimport))
#endif

class EXPORT MyClass { ... };

Then, while building your dll, you define IMPL, and while building users,
you don't. When the dll is being built, the compiler doesn't know if
clients are going to use MyClass's implicit copy constructor, so its
choices are:

1.) Generate it when it's dllexported and put it into the dll. Then, if
clients use it, they'll get it from the dll.
2.) Don't generate it when it's dllexported.
2a) Don't even generate the implementation when clients use it. Now the
copy constructor isn't defined anywhere and you'll get linker errors.
2b) Emit a weak definition into every TU that uses it. I think this would
work, but you end up with several copy constructors – if you wanted this,
you probably wouldn't have EXPORTed the class.

Because of this reasoning (I would guess), clang chooses 1 and defines all
implicit methods for dllexported classes. Now, in your case the definition
of some of these implicit methods causes an error. I suppose clang's logic
could instead be "only define all implicit methods that are valid", but I
think this can be different in different TUs. Consider:

  class A;
  class EXPORT B { unique_ptr<A> a_; };

I think the implicit destructor of B will be valid in TUs that happen to
include the header that defines A but not in others. So that doesn't seem
like a good rule.

Nico

        Hans would know for sure, but I think this is intentional: Since
        AClass
        is dllexported, all its implicit functions get generated (so
        that they
        can be exported from the dll), which means they need to be
        semantically
        checked. If you give the class a deleted copy constructor and
        assignment
        operator, it might work.

    Where in the C++ standard is such behavior justified ?

The C++ standard doesn't talk about dllexport, so it won't say either way.

This isn't a question of standards, it's a question of practicality. The
way dllexport / dllimport are used is usually like so (think of a class
that has a valid copy constructor for a bit):

#ifdef IMPL
#define EXPORT __attribute__((dllexport))
#else
#define EXPORT __attribute((dllimport))
#endif

class EXPORT MyClass { ... };

Then, while building your dll, you define IMPL, and while building
users, you don't.

I know this of course.

When the dll is being built, the compiler doesn't know
if clients are going to use MyClass's implicit copy constructor, so its
choices are:

1.) Generate it when it's dllexported and put it into the dll. Then, if
clients use it, they'll get it from the dll.
2.) Don't generate it when it's dllexported.
2a) Don't even generate the implementation when clients use it. Now the
copy constructor isn't defined anywhere and you'll get linker errors.
2b) Emit a weak definition into every TU that uses it. I think this
would work, but you end up with several copy constructors – if you
wanted this, you probably wouldn't have EXPORTed the class.

Because of this reasoning (I would guess), clang chooses 1 and defines
all implicit methods for dllexported classes. Now, in your case the
definition of some of these implicit methods causes an error. I suppose
clang's logic could instead be "only define all implicit methods that
are valid", but I think this can be different in different TUs. Consider:

   class A;
   class EXPORT B { unique_ptr<A> a_; };

I think the implicit destructor of B will be valid in TUs that happen to
include the header that defines A but not in others. So that doesn't
seem like a good rule.

A TU that does not include the header that defines A is just being stupid so I think the compiler can choose to assume that an implicit destructor can be generated. And if there really is no definition for A then the design of B is just an error. The compiler should make reasonable choices. For B since C++11 is necesary for unique_ptr, deleted copy constructors and assignment operators should be generated if the compiler does not encounter any since unique_ptr is not copyable or assignable.

The problem is that you are forcing class designers, when a class is exportable, to generate copy constructors and assignment operators even when objects of that class are never meant to be copied or assigned. Of course the practical solution for this is to generate private declarations in C++03 and deleted declarations in C++11, but still it seems silly to enforce this. Instead the compiler should automatically generate these solutions when it sees that a class is not copyable or when it sees that a class is not assignable, and the designer has not provided his own declarations.

I really think it is wrong for clang to force class designers, even when exporting a class, to do something he would ordinarily never have to do in C++.

BTW gcc works correctly in the same situation in not generating any error when '__attribute__((dllexport))' is being used for mingw/gcc, if that means anything to clang.

Also VC++ works correctly in the same situation when __declspec(dllexport) is being used, if that means anything to clang.

Also as I noticed, when '__attribute__((__visibility____("default")))' is being used, which I assume is the Linux equivalent of 'exporting' a class, clang evidently does the right thing and generates no error. Why does it therefore operate differently with '__attribute__((dllexport))' ?

Is it a valid Boost solution to use '__attribute__((__visibility____("default")))' for clang on Windows targeting mingw/gcc as a workaround for this problem instead of having to change the exported class itself ? This of course would not solve the problem of using clang on Windows targeting VC++, where I assume '__attribute__((dllexport))' is correct and '__attribute__((__visibility____("default")))' would not be recognized, but I am less interested in that compiler for Boost.

There might be a Clang bug here, depending on whether the copy ctor is supposed to be implicitly deleted or not. I forget if having a base class with a private copy ctor implicitly deletes derived class copy ctors or not.

Clang’s class dllexport semantics are modeled on MSVC’s because they make more sense than GCC’s for PE/COFF. As Nico said, the idea is that we emit all these special members (and inline functions!) so that clients can dllimport them and not have to emit definitions. This is an intentional semantic difference from ELF’s visibility model, which has a different mechanism for ensuring that the addresses of inline functions are the same across DSO boundaries.

If you can find a way to delete, explicitly or implicitly, the unwanted copy ctor, then Clang should skip it while exporting the rest. If not, that’s a bug.

There might be a Clang bug here, depending on whether the copy ctor is
supposed to be implicitly deleted or not. I forget if having a base
class with a private copy ctor implicitly deletes derived class copy
ctors or not.

The second sentence above is not the case in my example, since there is no base class involved. I also did not compile in C++11 mode in my example AFAICS. Don't I need a command-line switch of -std=c++11 for that ?

Clang's class dllexport semantics are modeled on MSVC's because they
make more sense than GCC's for PE/COFF. As Nico said, the idea is that
we emit all these special members (and inline functions!) so that
clients can dllimport them and not have to emit definitions. This is an
intentional semantic difference from ELF's visibility model, which has a
different mechanism for ensuring that the addresses of inline functions
are the same across DSO boundaries.

If you can find a way to delete, explicitly or implicitly, the unwanted
copy ctor, then Clang should skip it while exporting the rest. If not,
that's a bug.

Let me start by saying that both mingw/mingw64/gcc on Windows and VC++ compiles the example I gave without error using their respective Windows export keywords. Clang as I have shown does not.

Whether or not clang generates an implicit copy constructor / copy-assignment operator when the user does not have one seems to me to be an irrelevant issue. If objects of the class are never copied/assigned why should clang generate an error ? This is regardless of whether the class is exported or not. I have a class that cannot be copied/assigned so naturally I see no need to create a user-defined copy constructor or copy-assignment operator. How can I be wrong not doing so ? Even when I export the class I am still telling users of the class that import it that it cannot be copied or assigned. That seems pretty clearcut to me. Clang now wants to tell me that if I export the class I must change how I code the class as to provide a user-defined copy constructor/assignment operator ( or a private declaration/deleted function depending on C++03/C++11 ) to satisfy clang ? That is not logically right from this end-user's point of view. I am also pretty sure that in C++03 if a class is not copyable I am not required to provide a user-defined copy constructor or private copy constructor declaration when defining the class.

Even in a C++11 compilation is it actually a C++ standard error if the programmer does not provide deleted versions of the copy constructor / assignment operator when objects of that class cannot be copied / assigned using the default generated copy constructor / assignment operator ? I do not think so. According to my reading of the C++11 standard as interpreted by Lippman in C++ Fifth Edition,

"The synthesized copy constructor is defined as deleted if the class has a member whose own copy constructor is deleted or inaccesible..."

"The synthesized copy-assignment operator is defined as deleted if a member has a deleted or inaccessible copy-assignment operator..."

I realized I am not quoting from the C++11 standard but unless Lippman is in error here I cannot see other than that clang is in error in the case I have presented.

I don't mind filing a bug report on this but I want to get some agreement here that clang is not doing the right thing even in the face of an "export" of the class. The job of defining an implicit copy constructor and copy-assignment operator is that of the compiler and if clang wants to claim that in the face of the "export" keyword it is not required to follow the standard C++ rules of how thiws should be done, I do not want to follow up with such a bug report.

There might be a Clang bug here, depending on whether the copy ctor is
supposed to be implicitly deleted or not. I forget if having a base
class with a private copy ctor implicitly deletes derived class copy
ctors or not.

The second sentence above is not the case in my example, since there is no
base class involved. I also did not compile in C++11 mode in my example
AFAICS. Don't I need a command-line switch of -std=c++11 for that ?

True, I misspoke, but it doesn't change my question: should the copy ctor
be implicitly deleted due to a member with a private copy ctor? I've
forgotten.

Clang's class dllexport semantics are modeled on MSVC's because they
make more sense than GCC's for PE/COFF. As Nico said, the idea is that
we emit all these special members (and inline functions!) so that
clients can dllimport them and not have to emit definitions. This is an
intentional semantic difference from ELF's visibility model, which has a
different mechanism for ensuring that the addresses of inline functions
are the same across DSO boundaries.

If you can find a way to delete, explicitly or implicitly, the unwanted
copy ctor, then Clang should skip it while exporting the rest. If not,
that's a bug.

Let me start by saying that both mingw/mingw64/gcc on Windows and VC++
compiles the example I gave without error using their respective Windows
export keywords. Clang as I have shown does not.

Yup. Ultimately, it's not possible to stamp out all inconsistencies between
compilers. We have to focus on the important ones.

Whether or not clang generates an implicit copy constructor /
copy-assignment operator when the user does not have one seems to me to be
an irrelevant issue. If objects of the class are never copied/assigned why
should clang generate an error ? This is regardless of whether the class is
exported or not. I have a class that cannot be copied/assigned so naturally
I see no need to create a user-defined copy constructor or copy-assignment
operator. How can I be wrong not doing so ? Even when I export the class I
am still telling users of the class that import it that it cannot be copied
or assigned. That seems pretty clearcut to me. Clang now wants to tell me
that if I export the class I must change how I code the class as to provide
a user-defined copy constructor/assignment operator ( or a private
declaration/deleted function depending on C++03/C++11 ) to satisfy clang ?
That is not logically right from this end-user's point of view. I am also
pretty sure that in C++03 if a class is not copyable I am not required to
provide a user-defined copy constructor or private copy constructor
declaration when defining the class.

Even in a C++11 compilation is it actually a C++ standard error if the
programmer does not provide deleted versions of the copy constructor /
assignment operator when objects of that class cannot be copied / assigned
using the default generated copy constructor / assignment operator ? I do
not think so. According to my reading of the C++11 standard as interpreted
by Lippman in C++ Fifth Edition,

"The synthesized copy constructor is defined as deleted if the class has a
member whose own copy constructor is deleted or inaccesible..."

"The synthesized copy-assignment operator is defined as deleted if a
member has a deleted or inaccessible copy-assignment operator..."

I realized I am not quoting from the C++11 standard but unless Lippman is
in error here I cannot see other than that clang is in error in the case I
have presented.

I don't mind filing a bug report on this but I want to get some agreement
here that clang is not doing the right thing even in the face of an
"export" of the class. The job of defining an implicit copy constructor and
copy-assignment operator is that of the compiler and if clang wants to
claim that in the face of the "export" keyword it is not required to follow
the standard C++ rules of how thiws should be done, I do not want to follow
up with such a bug report.

This seems like something worth filing a bug about. I guess even if the
copy ctor isn't technically deleted (probably because we're in C++98), it'd
be nice to avoid requiring it.

I haven't looked closely at your example yet, but if it's the case
that GCC and MSVC both compile the code fine, and Clang doesn't, it
sounds like we have a bug. Please file it at http://llvm.org/bugs, cc
me, and I will take a look when I'm back in the office.

Thanks,
Hans

I have reported the bug on the llvm Bugzilla given above for clang and the bug report page is http://llvm.org/bugs/show_bug.cgi?id=22591.

Thanks for addressing this issue.

There might be a Clang bug here, depending on whether the copy ctor is
supposed to be implicitly deleted or not. I forget if having a base
class with a private copy ctor implicitly deletes derived class copy
ctors or not.

The second sentence above is not the case in my example, since there is no
base class involved. I also did not compile in C++11 mode in my example
AFAICS. Don't I need a command-line switch of -std=c++11 for that ?

In C++11, the copy constructor would be deleted because the base class dtor
is inaccessible. In C++98, it will not be, because there is no notion of
deleted functions.

Clang's class dllexport semantics are modeled on MSVC's because they

make more sense than GCC's for PE/COFF. As Nico said, the idea is that
we emit all these special members (and inline functions!) so that
clients can dllimport them and not have to emit definitions. This is an
intentional semantic difference from ELF's visibility model, which has a
different mechanism for ensuring that the addresses of inline functions
are the same across DSO boundaries.

If you can find a way to delete, explicitly or implicitly, the unwanted
copy ctor, then Clang should skip it while exporting the rest. If not,
that's a bug.

Let me start by saying that both mingw/mingw64/gcc on Windows and VC++
compiles the example I gave without error using their respective Windows
export keywords. Clang as I have shown does not.

Presumably MSVC accepts because they build in C++11 mode (sort of -- they
don't *have* a separate C++98 mode). I would expect Clang to also accept
the code that MSVC accepts when run in C++11 mode.

Whether or not clang generates an implicit copy constructor /

copy-assignment operator when the user does not have one seems to me to be
an irrelevant issue. If objects of the class are never copied/assigned why
should clang generate an error ?

Because, as has already been stated, marking a class as dllexport causes
some of its implicitly-generated methods to be exported, which triggers
their definition. We may be getting the "some" wrong here, or the rules for
mingw and for MSVC might be different, but it *is* correct that we trigger
the definition of some implicit members in some cases when the class is
marked dllexport -- this is necessary for link compatibility with MSVC.

This is regardless of whether the class is exported or not. I have a class

that cannot be copied/assigned so naturally I see no need to create a
user-defined copy constructor or copy-assignment operator. How can I be
wrong not doing so ? Even when I export the class I am still telling users
of the class that import it that it cannot be copied or assigned. That
seems pretty clearcut to me. Clang now wants to tell me that if I export
the class I must change how I code the class as to provide a user-defined
copy constructor/assignment operator ( or a private declaration/deleted
function depending on C++03/C++11 ) to satisfy clang ? That is not
logically right from this end-user's point of view. I am also pretty sure
that in C++03 if a class is not copyable I am not required to provide a
user-defined copy constructor or private copy constructor declaration when
defining the class.

Even in a C++11 compilation is it actually a C++ standard error if the
programmer does not provide deleted versions of the copy constructor /
assignment operator when objects of that class cannot be copied / assigned
using the default generated copy constructor / assignment operator ? I do
not think so. According to my reading of the C++11 standard as interpreted
by Lippman in C++ Fifth Edition,

"The synthesized copy constructor is defined as deleted if the class has a
member whose own copy constructor is deleted or inaccesible..."

"The synthesized copy-assignment operator is defined as deleted if a
member has a deleted or inaccessible copy-assignment operator..."

I realized I am not quoting from the C++11 standard but unless Lippman is
in error here I cannot see other than that clang is in error in the case I
have presented.

You're using a language extension, so the guarantees of the C++ standard
are not relevant.

I don't mind filing a bug report on this but I want to get some agreement

        There might be a Clang bug here, depending on whether the copy
        ctor is
        supposed to be implicitly deleted or not. I forget if having a base
        class with a private copy ctor implicitly deletes derived class copy
        ctors or not.

    The second sentence above is not the case in my example, since there
    is no base class involved. I also did not compile in C++11 mode in
    my example AFAICS. Don't I need a command-line switch of -std=c++11
    for that ?

In C++11, the copy constructor would be deleted because the base class
dtor is inaccessible.

There is no base class in my example.

In C++98, it will not be, because there is no
notion of deleted functions.

Agreed. But I would expect in the case of my example that any compiler-defined copy constructor to be only a private declaration because the class is non-copyable. Either that or the compiler generates the standard copy constructor which copy constructs each member but does not flag it as an error because it is never actually called in the code.

        Clang's class dllexport semantics are modeled on MSVC's because they
        make more sense than GCC's for PE/COFF. As Nico said, the idea
        is that
        we emit all these special members (and inline functions!) so that
        clients can dllimport them and not have to emit definitions.
        This is an
        intentional semantic difference from ELF's visibility model,
        which has a
        different mechanism for ensuring that the addresses of inline
        functions
        are the same across DSO boundaries.

        If you can find a way to delete, explicitly or implicitly, the
        unwanted
        copy ctor, then Clang should skip it while exporting the rest.
        If not,
        that's a bug.

    Let me start by saying that both mingw/mingw64/gcc on Windows and
    VC++ compiles the example I gave without error using their
    respective Windows export keywords. Clang as I have shown does not.

Presumably MSVC accepts because they build in C++11 mode (sort of --
they don't *have* a separate C++98 mode). I would expect Clang to also
accept the code that MSVC accepts when run in C++11 mode.

You are saying that in C++11 mode the code in my example should compile without error but in non-C++11 mode the code in my example should be in error.

    Whether or not clang generates an implicit copy constructor /
    copy-assignment operator when the user does not have one seems to me
    to be an irrelevant issue. If objects of the class are never
    copied/assigned why should clang generate an error ?

Because, as has already been stated, marking a class as dllexport causes
some of its implicitly-generated methods to be exported, which triggers
their definition. We may be getting the "some" wrong here, or the rules
for mingw and for MSVC might be different, but it *is* correct that we
trigger the definition of some implicit members in some cases when the
class is marked dllexport -- this is necessary for link compatibility
with MSVC.

I am using the clang for Windows which targets mingw(64)/gcc not the one that targets MSVC.

    This is regardless of whether the class is exported or not. I have a
    class that cannot be copied/assigned so naturally I see no need to
    create a user-defined copy constructor or copy-assignment operator.
    How can I be wrong not doing so ? Even when I export the class I am
    still telling users of the class that import it that it cannot be
    copied or assigned. That seems pretty clearcut to me. Clang now
    wants to tell me that if I export the class I must change how I code
    the class as to provide a user-defined copy constructor/assignment
    operator ( or a private declaration/deleted function depending on
    C++03/C++11 ) to satisfy clang ? That is not logically right from
    this end-user's point of view. I am also pretty sure that in C++03
    if a class is not copyable I am not required to provide a
    user-defined copy constructor or private copy constructor
    declaration when defining the class.

    Even in a C++11 compilation is it actually a C++ standard error if
    the programmer does not provide deleted versions of the copy
    constructor / assignment operator when objects of that class cannot
    be copied / assigned using the default generated copy constructor /
    assignment operator ? I do not think so. According to my reading of
    the C++11 standard as interpreted by Lippman in C++ Fifth Edition,

    "The synthesized copy constructor is defined as deleted if the class
    has a member whose own copy constructor is deleted or inaccesible..."

    "The synthesized copy-assignment operator is defined as deleted if a
    member has a deleted or inaccessible copy-assignment operator..."

    I realized I am not quoting from the C++11 standard but unless
    Lippman is in error here I cannot see other than that clang is in
    error in the case I have presented.

You're using a language extension, so the guarantees of the C++ standard
are not relevant.

You can make your own rule based on the fact that exporting a class is not mentioned in the C++ standard but I think your rule is wrong. You are telling programmers that they must supply a user-defined copy constructor for a class which is exported and is non-copyable, even when objects of the class are not meant to be copied and are not copied in code. Furthermore your previous comment implies that this must be done only in non-C++11 mode.

        There might be a Clang bug here, depending on whether the copy
        ctor is
        supposed to be implicitly deleted or not. I forget if having a
base
        class with a private copy ctor implicitly deletes derived class
copy
        ctors or not.

    The second sentence above is not the case in my example, since there
    is no base class involved. I also did not compile in C++11 mode in
    my example AFAICS. Don't I need a command-line switch of -std=c++11
    for that ?

In C++11, the copy constructor would be deleted because the base class
dtor is inaccessible.

There is no base class in my example.

Sorry, I was addressing Reid's question here. In your example, the copy
constructor would be deleted because you have a non-copyable member, so the
effect is the same.

In C++98, it will not be, because there is no

notion of deleted functions.

Agreed. But I would expect in the case of my example that any
compiler-defined copy constructor to be only a private declaration because
the class is non-copyable. Either that or the compiler generates the
standard copy constructor which copy constructs each member but does not
flag it as an error because it is never actually called in the code.

That's a possible approach. We'll need someone to experiment with mingw to
discover what we should do to match it.

        Clang's class dllexport semantics are modeled on MSVC's because

they
        make more sense than GCC's for PE/COFF. As Nico said, the idea
        is that
        we emit all these special members (and inline functions!) so that
        clients can dllimport them and not have to emit definitions.
        This is an
        intentional semantic difference from ELF's visibility model,
        which has a
        different mechanism for ensuring that the addresses of inline
        functions
        are the same across DSO boundaries.

        If you can find a way to delete, explicitly or implicitly, the
        unwanted
        copy ctor, then Clang should skip it while exporting the rest.
        If not,
        that's a bug.

    Let me start by saying that both mingw/mingw64/gcc on Windows and
    VC++ compiles the example I gave without error using their
    respective Windows export keywords. Clang as I have shown does not.

Presumably MSVC accepts because they build in C++11 mode (sort of --
they don't *have* a separate C++98 mode). I would expect Clang to also
accept the code that MSVC accepts when run in C++11 mode.

You are saying that in C++11 mode the code in my example should compile
without error but in non-C++11 mode the code in my example should be in
error.

I was not talking about what should happen, I was talking about what I
expect to happen, and why. Our behavior in MSVC + C++98 mode is not
interesting, because there is no other compiler to be compatible with in
that case, and as a result it's not really a mode that we care much about.
Our behavior in either C++11 mode is probably fine. The interesting case is
how we should behave in mingw + C++98 mode; it seems that's the one we get
wrong, by deviating from mingw's behavior.

    Whether or not clang generates an implicit copy constructor /

    copy-assignment operator when the user does not have one seems to me
    to be an irrelevant issue. If objects of the class are never
    copied/assigned why should clang generate an error ?

Because, as has already been stated, marking a class as dllexport causes
some of its implicitly-generated methods to be exported, which triggers
their definition. We may be getting the "some" wrong here, or the rules
for mingw and for MSVC might be different, but it *is* correct that we
trigger the definition of some implicit members in some cases when the
class is marked dllexport -- this is necessary for link compatibility
with MSVC.

I am using the clang for Windows which targets mingw(64)/gcc not the one
that targets MSVC.

Right; I suspect we're getting the mingw compatibility wrong here, by
assuming it's the same as MSVC (and it's possible that we get the MSVC
compatibility wrong too, in the same way).

    This is regardless of whether the class is exported or not. I have a

    class that cannot be copied/assigned so naturally I see no need to
    create a user-defined copy constructor or copy-assignment operator.
    How can I be wrong not doing so ? Even when I export the class I am
    still telling users of the class that import it that it cannot be
    copied or assigned. That seems pretty clearcut to me. Clang now
    wants to tell me that if I export the class I must change how I code
    the class as to provide a user-defined copy constructor/assignment
    operator ( or a private declaration/deleted function depending on
    C++03/C++11 ) to satisfy clang ? That is not logically right from
    this end-user's point of view. I am also pretty sure that in C++03
    if a class is not copyable I am not required to provide a
    user-defined copy constructor or private copy constructor
    declaration when defining the class.

    Even in a C++11 compilation is it actually a C++ standard error if
    the programmer does not provide deleted versions of the copy
    constructor / assignment operator when objects of that class cannot
    be copied / assigned using the default generated copy constructor /
    assignment operator ? I do not think so. According to my reading of
    the C++11 standard as interpreted by Lippman in C++ Fifth Edition,

    "The synthesized copy constructor is defined as deleted if the class
    has a member whose own copy constructor is deleted or inaccesible..."

    "The synthesized copy-assignment operator is defined as deleted if a
    member has a deleted or inaccessible copy-assignment operator..."

    I realized I am not quoting from the C++11 standard but unless
    Lippman is in error here I cannot see other than that clang is in
    error in the case I have presented.

You're using a language extension, so the guarantees of the C++ standard
are not relevant.

You can make your own rule based on the fact that exporting a class is not
mentioned in the C++ standard but I think your rule is wrong. You are
telling programmers that they must supply a user-defined copy constructor
for a class which is exported and is non-copyable, even when objects of the
class are not meant to be copied and are not copied in code. Furthermore
your previous comment implies that this must be done only in non-C++11 mode.

For ABI compatibility, we are required to follow other compilers when we
implement their dllexport attribute. We're not making up any rule here
ourselves. If we're doing something different from what those other
compilers do (as we evidently are), that is a bug. But it doesn't matter
what the relevant language standards say, because this is an extension --
in the cases where we need to implicitly define a copy operation for ABI
compatibility, we will do so, even if the source code doesn't otherwise
"use" that function.

    I don't mind filing a bug report on this but I want to get some