[boost] [winapi] Problem with the latest clang on Windows

193 views
Skip to first unread message

Edward Diener

unread,
May 31, 2015, 8:08:21 PM5/31/15
to bo...@lists.boost.org
Updates to clang on Windows have broken the use of clang with the
[winapi] library. I do not know if this has occurred in the past but it
seems to have occurred recently when I build the latest clang from
source and use it on Windows to compile build Boost libraries which use
the internal winapi library.

Preprocessing clang and gcc output for a given call in the Boost winapi
library and in the corresponding mingw windows.h shows that both
compilers view the same source but treat them differently.

As an example let's look at the GetSystemTimeAsFileTime call. The
preprocessed source for both clang and gcc shows:

In the Boost winapi it is:

__attribute__((dllimport)) void __attribute__((__stdcall__))
GetSystemTimeAsFileTime(FILETIME_* lpFileTime);

In the mingw/gcc windows.h it is:

void __attribute__((__stdcall__)) GetSystemTimeAsFileTime(LPFILETIME);

where the FILETIME_ and LPFILETIME are the same.

When gcc sees these two declarations in the two different headers it
says everything is OK.

When clang sees these two declarations in the two different headers it
gives an error:

In file included from test_winapi.cpp:9:
In file included from /mingw/include\windows.h:62:
/mingw/include\winbase.h:1397:24: error: conflicting types for
'GetSystemTimeAsFileTime'
WINBASEAPI void WINAPI GetSystemTimeAsFileTime(LPFILETIME);
^
..\..\..\boost/detail/winapi/time.hpp:70:9: note: previous declaration
is here
GetSystemTimeAsFileTime(FILETIME_* lpFileTime);
^

For this line in boost/detail/winapi/time.hpp

__declspec(dllimport) void WINAPI
GetSystemTimeAsFileTime(FILETIME_* lpFileTime);

It seems like the fix for clang is to leave out the
__declspec(dllimport) portion of all these Boost winapi calls while
leaving it in for everybody else. I am discussing this on the clang
developers mailing list but it seems like they are pretty adamant that
if they see __attribute__((dllimport)) in from of a function declaration
and do not see it in front of another function declaration, despite the
rest of the signatire being the same, the two declarations are not the
same function being declared and therefore an error because of ODR.









_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Niall Douglas

unread,
May 31, 2015, 8:43:45 PM5/31/15
to bo...@lists.boost.org
On 31 May 2015 at 20:07, Edward Diener wrote:

> It seems like the fix for clang is to leave out the
> __declspec(dllimport) portion of all these Boost winapi calls while
> leaving it in for everybody else. I am discussing this on the clang
> developers mailing list but it seems like they are pretty adamant that
> if they see __attribute__((dllimport)) in from of a function declaration
> and do not see it in front of another function declaration, despite the
> rest of the signatire being the same, the two declarations are not the
> same function being declared and therefore an error because of ODR.

Oddly enough this topic came up at C++ Now when I was chatting with
Chandler.

They are immovable on clang being standards conformant in mingw mode.
That means API declarations must match. Else it's a bug, and it will
be errored out. Just because MSVC uses sloppy declspec doesn't mean
it's valid C++. They will not back down, or change their mind on
this, period.

Switching clang into msvc mode makes everything just work.

For reference. Boost.Thread no longer compiles at all on clang in
mingw mode for the same reason, but nearly gets there with clang in
msvc mode. I suspect plenty more libraries are similar. At some point
we'll need to go fix up all our code.

Niall

--
ned Productions Limited Consulting
http://www.nedproductions.biz/
http://ie.linkedin.com/in/nialldouglas/


Edward Diener

unread,
May 31, 2015, 9:32:15 PM5/31/15
to bo...@lists.boost.org
On 5/31/2015 8:44 PM, Niall Douglas wrote:
> On 31 May 2015 at 20:07, Edward Diener wrote:
>
>> It seems like the fix for clang is to leave out the
>> __declspec(dllimport) portion of all these Boost winapi calls while
>> leaving it in for everybody else. I am discussing this on the clang
>> developers mailing list but it seems like they are pretty adamant that
>> if they see __attribute__((dllimport)) in from of a function declaration
>> and do not see it in front of another function declaration, despite the
>> rest of the signatire being the same, the two declarations are not the
>> same function being declared and therefore an error because of ODR.
>
> Oddly enough this topic came up at C++ Now when I was chatting with
> Chandler.
>
> They are immovable on clang being standards conformant in mingw mode.
> That means API declarations must match. Else it's a bug, and it will
> be errored out. Just because MSVC uses sloppy declspec doesn't mean
> it's valid C++. They will not back down, or change their mind on
> this, period.

Evidently from my OP it is gcc being sloppy.

>
> Switching clang into msvc mode makes everything just work.

Clang in MSVC mode means you're dealing with a compiler trying to
emulate a broken preprocessor. No thanks ! I already had this discussion
on the clang mailing lists and since they are adamant that they must
attempt to emulate the VC++ preprocessor bugs in all situations I will
not use that mode. I suggested to them a system by which they could
emulate the broken VC++ preprocessor for VC++ headers which need it and
otherwise support a C++ standard compliant preprocessor everywhere else,
but they did not want to consider it.

So it doesn't make everything just work. In fact it may break any Boost
library which uses Boost PP. And that's not a problem which Boost PP is
going to try to solve.

Boost build also doesn't have built-in support for clang in VC++ mode on
Windows but works fine with clang in gcc mode on Windows.

>
> For reference. Boost.Thread no longer compiles at all on clang in
> mingw mode for the same reason, but nearly gets there with clang in
> msvc mode. I suspect plenty more libraries are similar. At some point
> we'll need to go fix up all our code.

If we fix up Boost win32 we might be OK. That was the gist of my OP.

Paul Mensonides

unread,
May 31, 2015, 9:40:45 PM5/31/15
to bo...@lists.boost.org
On 5/31/2015 6:31 PM, Edward Diener wrote:
> On 5/31/2015 8:44 PM, Niall Douglas wrote:
>> On 31 May 2015 at 20:07, Edward Diener wrote:

>> Switching clang into msvc mode makes everything just work.
>
> Clang in MSVC mode means you're dealing with a compiler trying to
> emulate a broken preprocessor. No thanks ! I already had this discussion
> on the clang mailing lists and since they are adamant that they must
> attempt to emulate the VC++ preprocessor bugs in all situations I will
> not use that mode. I suggested to them a system by which they could
> emulate the broken VC++ preprocessor for VC++ headers which need it and
> otherwise support a C++ standard compliant preprocessor everywhere else,
> but they did not want to consider it.
>
> So it doesn't make everything just work. In fact it may break any Boost
> library which uses Boost PP. And that's not a problem which Boost PP is
> going to try to solve.
>
> Boost build also doesn't have built-in support for clang in VC++ mode on
> Windows but works fine with clang in gcc mode on Windows.

Agreed. Clang in MSVC mode is junk.

Regards,
Paul Mensonides

Andrey Semashev

unread,
Jun 1, 2015, 4:03:13 AM6/1/15
to bo...@lists.boost.org
There's this possibly related ticket:

https://svn.boost.org/trac/boost/ticket/11338

I'm puzzled how the function can be not dllimport as it is implemented in
kernel32.dll. MS Windows SDK defines WINBASEAPI to be __declspec(dllimport)
and so is MinGW64 (see winbase.h and winnt.h). Does clang use its own SDK?

Also, is it known for sure that the attribute is what's causing the faulre?
Because formally, the winapi declaration also involves structures different
from those in windows.h and I don't see an easy way around this.

Edward Diener

unread,
Jun 1, 2015, 10:08:44 AM6/1/15
to bo...@lists.boost.org
gcc and clang on Windows can use the win32 implementation provided by
mingw. Evidently the mingw header files translates WINBASEAPI to be empty.

I will try gcc with mingw64 to see if it is different. Unfortunately I
have had problems building/using clang with mingw64 and clang even
acknowledges that it only supports mingw and not mingw64 on Windows. The
suggested a way to get clang working with mingw64 but I have not been
able to make that work.

I have been asked by clang to file a bug report regarding this
situation, and wil do that.

>
> Also, is it known for sure that the attribute is what's causing the faulre?
> Because formally, the winapi declaration also involves structures different
> from those in windows.h and I don't see an easy way around this.

Is the FILETIME struct in winapi different than that in windows.h ? If
it is it means that you can never include Boost's winapi and the
equivalent windows.h struct in the same TU without having a compile
error. I don't think that Boost's winapi could have been designed that way.

Edward Diener

unread,
Jun 1, 2015, 10:39:02 AM6/1/15
to bo...@lists.boost.org
With mingw64 WINBASEAPI is __attribute__((dllimport)). I will ask on the
mingw mailing list why WINBASEAPI is empty in mingw as opposed to mingw64.

Andrey Semashev

unread,
Jun 1, 2015, 10:48:45 AM6/1/15
to bo...@lists.boost.org
On Monday 01 June 2015 10:07:56 Edward Diener wrote:
> On 6/1/2015 4:02 AM, Andrey Semashev wrote:
> >
> > I'm puzzled how the function can be not dllimport as it is implemented in
> > kernel32.dll. MS Windows SDK defines WINBASEAPI to be
> > __declspec(dllimport)
> > and so is MinGW64 (see winbase.h and winnt.h). Does clang use its own SDK?
>
> gcc and clang on Windows can use the win32 implementation provided by
> mingw. Evidently the mingw header files translates WINBASEAPI to be empty.
>
> I will try gcc with mingw64 to see if it is different. Unfortunately I
> have had problems building/using clang with mingw64 and clang even
> acknowledges that it only supports mingw and not mingw64 on Windows. The
> suggested a way to get clang working with mingw64 but I have not been
> able to make that work.

My understanding is that MinGW (http://mingw.org/) was discontinued in favor
of MinGW64 (http://mingw-w64.org/). Not sure if we should support it.

Anyway, if it turns out that there is no dllimport just in the MinGW SDK then
I'm inclined to think it's a bug in the SDK. If we decide so, we could add a
workaround if it is possible to detect that particular SDK.

> I have been asked by clang to file a bug report regarding this
> situation, and wil do that.

Thanks. Could you post the link to the bug report?

> > Also, is it known for sure that the attribute is what's causing the
> > faulre?
> > Because formally, the winapi declaration also involves structures
> > different
> > from those in windows.h and I don't see an easy way around this.
>
> Is the FILETIME struct in winapi different than that in windows.h ? If
> it is it means that you can never include Boost's winapi and the
> equivalent windows.h struct in the same TU without having a compile
> error. I don't think that Boost's winapi could have been designed that way.

The structure itself is binary compatible with that defined in Windows SDK.
But it has a different name and is declared in the boost::detail::winapi
namespace, so from the language standpoint it is a distinct type. The WinAPI
functions have extern "C" linkage, which makes them have the same mangled name
as the real ones in Windows SDK. If the compiler checks that C++ declarations
of the similarly named extern "C" functions have the same argument types then
this is a showstopper and I don't think we can do anything except to always
include and use windows.h on that compiler.

Peter Dimov

unread,
Jun 1, 2015, 11:03:09 AM6/1/15
to bo...@lists.boost.org
Andrey Semashev wrote:

> If the compiler checks that C++ declarations of the similarly named extern
> "C" functions have the same argument types then this is a showstopper and
> I don't think we can do anything except to always include and use
> windows.h on that compiler.

Maybe we can, but I'm not sure if it's worth it.

// at global scope
struct FILETIME;
extern "C" __declspec(dllimport) void __stdcall
GetSystemTimeAsFileTime(FILETIME*);

namespace winapi
{
struct FILETIME { ... };

inline void GetSystemTimeAsFileTime( FILETIME * p )
{
::GetSystemTimeAsFileTime( (::FILETIME*)p );

Andrey Semashev

unread,
Jun 1, 2015, 11:16:06 AM6/1/15
to bo...@lists.boost.org
On Monday 01 June 2015 18:01:48 Peter Dimov wrote:
> Andrey Semashev wrote:
> > If the compiler checks that C++ declarations of the similarly named extern
> > "C" functions have the same argument types then this is a showstopper and
> > I don't think we can do anything except to always include and use
> > windows.h on that compiler.
>
> Maybe we can, but I'm not sure if it's worth it.
>
> // at global scope
> struct FILETIME;
> extern "C" __declspec(dllimport) void __stdcall
> GetSystemTimeAsFileTime(FILETIME*);
>
> namespace winapi
> {
> struct FILETIME { ... };
>
> inline void GetSystemTimeAsFileTime( FILETIME * p )
> {
> ::GetSystemTimeAsFileTime( (::FILETIME*)p );
> }
> }

Interesting idea, I haven't though about it.

Edward Diener

unread,
Jun 1, 2015, 11:24:22 AM6/1/15
to bo...@lists.boost.org
On 6/1/2015 10:48 AM, Andrey Semashev wrote:
> On Monday 01 June 2015 10:07:56 Edward Diener wrote:
>> On 6/1/2015 4:02 AM, Andrey Semashev wrote:
>>>
>>> I'm puzzled how the function can be not dllimport as it is implemented in
>>> kernel32.dll. MS Windows SDK defines WINBASEAPI to be
>>> __declspec(dllimport)
>>> and so is MinGW64 (see winbase.h and winnt.h). Does clang use its own SDK?
>>
>> gcc and clang on Windows can use the win32 implementation provided by
>> mingw. Evidently the mingw header files translates WINBASEAPI to be empty.
>>
>> I will try gcc with mingw64 to see if it is different. Unfortunately I
>> have had problems building/using clang with mingw64 and clang even
>> acknowledges that it only supports mingw and not mingw64 on Windows. The
>> suggested a way to get clang working with mingw64 but I have not been
>> able to make that work.
>
> My understanding is that MinGW (http://mingw.org/) was discontinued in favor
> of MinGW64 (http://mingw-w64.org/). Not sure if we should support it.

What do you mean by "discontinued" ? MingW is still around. A clang
build targeting gcc on Windows works out of the box with MingW and not
with MingW64. I have already discussed this on the clang developer's
mailing list and the last response was:

"You're completely right that supporting mingw64 is better than
supporting than mingw.org. With open source projects, someone needs to
push http://reviews.llvm.org/D5268 through the process until commit.
This takes time... I hope to get to this someday."

>
> Anyway, if it turns out that there is no dllimport just in the MinGW SDK then
> I'm inclined to think it's a bug in the SDK. If we decide so, we could add a
> workaround if it is possible to detect that particular SDK.
>
>> I have been asked by clang to file a bug report regarding this
>> situation, and wil do that.
>
> Thanks. Could you post the link to the bug report?

I have not done it yet but when I do I will provide the link.

>
>>> Also, is it known for sure that the attribute is what's causing the
>>> faulre?
>>> Because formally, the winapi declaration also involves structures
>>> different
>>> from those in windows.h and I don't see an easy way around this.
>>
>> Is the FILETIME struct in winapi different than that in windows.h ? If
>> it is it means that you can never include Boost's winapi and the
>> equivalent windows.h struct in the same TU without having a compile
>> error. I don't think that Boost's winapi could have been designed that way.
>
> The structure itself is binary compatible with that defined in Windows SDK.
> But it has a different name and is declared in the boost::detail::winapi
> namespace, so from the language standpoint it is a distinct type. The WinAPI
> functions have extern "C" linkage, which makes them have the same mangled name
> as the real ones in Windows SDK. If the compiler checks that C++ declarations
> of the similarly named extern "C" functions have the same argument types then
> this is a showstopper and I don't think we can do anything except to always
> include and use windows.h on that compiler.

What does the C++ standard say about the extern "C" declarations
duplicating the same name as regular declarations but different types.
Is it an ODR violation ? Maybe that is what the clang problem is about
although gcc does not feel it is a problem seeing the exact same
preprocessed output.

Vicente J. Botet Escriba

unread,
Jun 1, 2015, 1:14:26 PM6/1/15
to bo...@lists.boost.org
Le 01/06/15 10:02, Andrey Semashev a écrit :
I have no access to a windows environment.

I could create a branch and do my best to port to Boost.WinAPI if
someone is ready to test it.

I would also accept any working patch.

Best,
Vicente

Andrey Semashev

unread,
Jun 1, 2015, 3:12:26 PM6/1/15
to bo...@lists.boost.org
On Monday 01 June 2015 11:23:36 Edward Diener wrote:
> On 6/1/2015 10:48 AM, Andrey Semashev wrote:
> >
> > My understanding is that MinGW (http://mingw.org/) was discontinued in
> > favor of MinGW64 (http://mingw-w64.org/). Not sure if we should support
> > it.
>
> What do you mean by "discontinued" ?

I mean it's not being released for quite some time. The last stable compiler
release I can see was in 2013. Mailing lists[1][2] activity is rather low.
Combined with the fact that the compiler still doesn't support 64-bit targets,
this is a strong indication to me that the project is pretty much dead.

> What does the C++ standard say about the extern "C" declarations
> duplicating the same name as regular declarations but different types.
> Is it an ODR violation ? Maybe that is what the clang problem is about
> although gcc does not feel it is a problem seeing the exact same
> preprocessed output.

I could only find 7.5/6:

...Two declarations for a function with C language linkage
with the same function name (ignoring the namespace names
that qualify it) that appear in different namespace scopes
refer to the same function....

It doesn't say anything about argument types. ODR also doesn't apply here
since we're talking about the function declaration, not its definition.

[1] http://dir.gmane.org/gmane.comp.gnu.mingw.devel
[2] http://dir.gmane.org/gmane.comp.gnu.mingw.user

Andrey Semashev

unread,
Jun 1, 2015, 3:34:26 PM6/1/15
to bo...@lists.boost.org
On Monday 01 June 2015 19:13:58 Vicente J. Botet Escriba wrote:
> Le 01/06/15 10:02, Andrey Semashev a écrit :
> >
> > There's this possibly related ticket:
> >
> > https://svn.boost.org/trac/boost/ticket/11338
>
> I have no access to a windows environment.
>
> I could create a branch and do my best to port to Boost.WinAPI if
> someone is ready to test it.
>
> I would also accept any working patch.

Unfortunately, I don't have much time lately to prepare a patch. I could test
the branch on the local VM, though. We also have quite a few Windows testers.

Edward Diener

unread,
Jun 1, 2015, 5:58:21 PM6/1/15
to bo...@lists.boost.org
On 6/1/2015 3:12 PM, Andrey Semashev wrote:
> On Monday 01 June 2015 11:23:36 Edward Diener wrote:
>> On 6/1/2015 10:48 AM, Andrey Semashev wrote:
>>>
>>> My understanding is that MinGW (http://mingw.org/) was discontinued in
>>> favor of MinGW64 (http://mingw-w64.org/). Not sure if we should support
>>> it.
>>
>> What do you mean by "discontinued" ?
>
> I mean it's not being released for quite some time. The last stable compiler
> release I can see was in 2013. Mailing lists[1][2] activity is rather low.
> Combined with the fact that the compiler still doesn't support 64-bit targets,
> this is a strong indication to me that the project is pretty much dead.

There is still activity on those mailing lists and I have seen nothing
on the mingw site that suggests they have come to an end. If clang
builds supported mingw64 then I agree that I would not bother with
setting up mingw, but since clang/mingw64 is hardly a viable option I
still maintain mingw for testing. I quoted you with what one of the
clang developers said about clang/mingw64. I have not made a further
issue with him or anyone else on the clang mailing list about it.

>
>> What does the C++ standard say about the extern "C" declarations
>> duplicating the same name as regular declarations but different types.
>> Is it an ODR violation ? Maybe that is what the clang problem is about
>> although gcc does not feel it is a problem seeing the exact same
>> preprocessed output.
>
> I could only find 7.5/6:
>
> ...Two declarations for a function with C language linkage
> with the same function name (ignoring the namespace names
> that qualify it) that appear in different namespace scopes
> refer to the same function....
>
> It doesn't say anything about argument types. ODR also doesn't apply here
> since we're talking about the function declaration, not its definition.

OK, so just declaring a function with the same name but different
signature doesn't mean a compiler error. But when we invoke the function
with a signature that matches one of the declarations does the C++
standard say it is an error because another declaration with the same
name but a different signature exists ? Evidently clang thinks it is an
error but gcc does not.

Andrey Semashev

unread,
Jun 1, 2015, 6:58:12 PM6/1/15
to bo...@lists.boost.org
I didn't find any specifics on this (but I could be missing something). The
extern "C" linkage affects overload resolution (13.3.2/3), so that if there
are two viable extern "C" function declarations that are in different
namespaces are visible at the call site, the two declarations do not conflict
as they are considered to declare the one and only extern "C" function. But
then again, the example does not consider the case when the two declarations
differ in arguments. The standard also mentions that language-specific linkage
may have other effects, such as special name mangling or calling conventions
(7.5/1), but naturally, it doesn't go into specifics of these effects.

Since other than the above there are no special treatment of extern "C"
function calls from the language perspective, I would assume that as long as
the call in unambiguous by the C++ overload resolution rules, the language
should allow it.

If clang folks say this should not compile then perhaps they could point to
the relevant part of the standard.

Niall Douglas

unread,
Jun 1, 2015, 9:11:06 PM6/1/15
to bo...@lists.boost.org
On 2 Jun 2015 at 1:57, Andrey Semashev wrote:

> Since other than the above there are no special treatment of extern "C"
> function calls from the language perspective, I would assume that as long as
> the call in unambiguous by the C++ overload resolution rules, the language
> should allow it.
>
> If clang folks say this should not compile then perhaps they could point to
> the relevant part of the standard.

Obviously declspec anything is non-standard.

I believe the reason clang is insisting on this behaviour is because
declspec is part of the type definition. You can see this in how
pointers to functions retain their declspec attributes in the pointer
type.

Therefore not always specifying them consistently is an ODR
violation, and therefore clang is being right here. GCC matches
MSVC's incorrectness here for ease of life. As does clang when in
MSVC mode.

Regarding mingw's broken headers which don't specify dllimport
correctly for kernel32 imports, yeah that's one of a long litany of
problems in mingw's headers. I in fact gave up on mingw support in
AFIO in the v1.3 release, it was becoming too painful to keep working
around their severe quality problems. AFIO now only supports
mingw-w64.

Mingw-w64 have done an excellent job, and are light years ahead of
mingw in quality control and stability. They also support the C++ 11
<thread> header, which mingw does not.

Regarding why clang is not on mingw-w64 yet, apparently it may be
political. See
http://sourceforge.net/p/mingw-w64/mailman/mingw-w64-public/thread/873
8aihl...@wanadoo.es/. I agree with the assessment that mingw
support is not a priority for the clang devs compared to MSVC
support, but I am not aware of any active campaign against mingw-w64
support. It's more no one could be bothered relative to other things
to do I think.

Anyway, from my own perspective whilst it would be nice if
mingw-clang was working, it's no showstopper for me personally. MinGW
users are a tiny proportion of the user base, sufficiently tiny that
GCC is good enough for now. I see mingw-w64 is very shortly going to
release a GCC 5.1 build, it's hardly like MinGW users are suffering
from ancient GCC tooling or something.

winclang is a whole different beast though. That's an enormous threat
to MSVC in the medium term. Microsoft may, of course, just go ahead
and bundle a winclang toolset in future Visual Studios as an equally
supported alternative to MSVC. That would be *enormous* for anyone
trying to do modern C++ on Windows, though MSVC is coming along
hugely of late and it's still vastly faster to compile than clang,
and I suspect always will be.

Edward Diener

unread,
Jun 1, 2015, 9:26:16 PM6/1/15
to bo...@lists.boost.org
Clang bug report at:

https://llvm.org/bugs/show_bug.cgi?id=23722

You can view their response if/when it comes.

Edward Diener

unread,
Jun 1, 2015, 9:50:03 PM6/1/15
to bo...@lists.boost.org
I agree that mingw64 is much better but clang can only target gcc from
mingw, and not mingw64, without alot of hacking I am not in the mood to
try. In order to run clang on Windows using bjam to test Boost library
code I have to build clang targeting mingw/gcc. There is no other choice
unless clang provides mingw64/gcc as a possible target.

>
> Regarding why clang is not on mingw-w64 yet, apparently it may be
> political. See
> http://sourceforge.net/p/mingw-w64/mailman/mingw-w64-public/thread/873
> 8aihl...@wanadoo.es/.

That does not appear to be apropos the issue of building clang with
mingw64/gcc. Instead it appears to be about using clang to create
mingw64 builds. Did I miss something in that discussion ?

> I agree with the assessment that mingw
> support is not a priority for the clang devs compared to MSVC
> support, but I am not aware of any active campaign against mingw-w64
> support. It's more no one could be bothered relative to other things
> to do I think.

As explained before the current MSVC build of clang is absolutely
useless for testing Boost, unless you are not using Boost PP at all.
Which is fine but many libraries are for a good reason.

>
> Anyway, from my own perspective whilst it would be nice if
> mingw-clang was working, it's no showstopper for me personally. MinGW
> users are a tiny proportion of the user base, sufficiently tiny that
> GCC is good enough for now. I see mingw-w64 is very shortly going to
> release a GCC 5.1 build, it's hardly like MinGW users are suffering
> from ancient GCC tooling or something.

I also test gcc on Windows using mingw64. It works very nicely. But it
is good to try clang also with Boost libraries. Despite what you may
believe both gcc and clang are better C++ standard conformant compilers
than even the most recent VC++13 version. That's not to say I haven't
used VC++ extensively in corporate consulting jobs. I have and it has
done the job for the type of programming corporations desire. But if you
are talking about adherence to the C++ standard VC++ has always been
behind, never mind the broken preprocessor.

>
> winclang is a whole different beast though. That's an enormous threat
> to MSVC in the medium term. Microsoft may, of course, just go ahead
> and bundle a winclang toolset in future Visual Studios as an equally
> supported alternative to MSVC. That would be *enormous* for anyone
> trying to do modern C++ on Windows, though MSVC is coming along
> hugely of late and it's still vastly faster to compile than clang,
> and I suspect always will be.

The slow compilation speed of clang has been also discussed on their
developers mailing list. But that's not a showstopper.

>
> Niall

Edward Diener

unread,
Jun 2, 2015, 2:35:22 AM6/2/15
to bo...@lists.boost.org
The reply from clang was quick on the bug report:

"The problem is that the two function declarations have different
parameter types. The windows.h version takes ::_FILETIME*, whereas the
boost version takes boost::detail::winapi::_FILETIME*. Because they're
'extern "C"' functions, they are redeclarations of the same function,
and are ill-formed because they have different types."

I have asked for the appropriate place in the C++ standard which
justifies the error.

Gavin Lambert

unread,
Jun 5, 2015, 3:05:33 AM6/5/15
to bo...@lists.boost.org
On 2/06/2015 18:34, Edward Diener wrote:
> The reply from clang was quick on the bug report:
>
> "The problem is that the two function declarations have different
> parameter types. The windows.h version takes ::_FILETIME*, whereas the
> boost version takes boost::detail::winapi::_FILETIME*. Because they're
> 'extern "C"' functions, they are redeclarations of the same function,
> and are ill-formed because they have different types."
>
> I have asked for the appropriate place in the C++ standard which
> justifies the error.

Standard or no, it does make sense that this should at least be a
warning, if not an error, unless the compiler can prove that the two
types really are binary compatible (and even that is still dubious
because it *can't* prove that they're semantically compatible).
Accidental parameter incompatibilities in C functions is the source of
many hard-to-locate bugs.

What is the reason that Boost WinAPI redeclares the structure? Can it
be changed to just use the one from the Windows headers (perhaps via
typedef, if the internal typename is needed for compatibility)?

(After writing the above, a cursory glance at the code suggests that it
does do that if BOOST_USE_WINDOWS_H is defined. So that changes the
question: under what conditions is that not defined?)

Andrey Semashev

unread,
Jun 5, 2015, 4:32:06 AM6/5/15
to bo...@lists.boost.org
On Friday 05 June 2015 19:04:51 Gavin Lambert wrote:
>
> What is the reason that Boost WinAPI redeclares the structure? Can it
> be changed to just use the one from the Windows headers (perhaps via
> typedef, if the internal typename is needed for compatibility)?
>
> (After writing the above, a cursory glance at the code suggests that it
> does do that if BOOST_USE_WINDOWS_H is defined. So that changes the
> question: under what conditions is that not defined?)

The reason of Boost.WinAPI existence is that people don't want to include
windows.h, especially in public headers. It is a heavy header that brings in
most of SDK. It depends on predefined macros, so including it once defines the
API users will be able to use; this is inconvenient for both Boost and its
users. Also, windows.h defines a few offending macros, like min/max.

In order to provide Windows API Boost.WinAPI has to redefine functions and
structures from Windows SDK in a binary compatible way but in the way it
doesn't conflict with windows.h. That's the current implementation.

BOOST_USE_WINDOWS_H is a macro that can be defined by the user if he wants
Boost to include windows.h. There's not much practical point in this except to
solve compatibility problems like in the original post.

Edward Diener

unread,
Jun 5, 2015, 5:46:16 AM6/5/15
to bo...@lists.boost.org
The clang explanation, when asked to point to the C++ standard, is:

"[dcl.link]/6: "At most one function with a particular name can have C
language linkage. Two declarations for a function with C language
linkage with the same function name (ignoring the namespace names that
qualify it) that appear in different namespace scopes refer to the same
function."

[basic.link]/10: "the types specified by all declarations referring to a
given variable or function shall be identical"

So the program is ill-formed because the same function is declared with
two different types."

Andrey Semashev

unread,
Jun 5, 2015, 6:22:25 AM6/5/15
to bo...@lists.boost.org
On Friday 05 June 2015 05:45:18 Edward Diener wrote:
>
> The clang explanation, when asked to point to the C++ standard, is:
>
> "[dcl.link]/6: "At most one function with a particular name can have C
> language linkage. Two declarations for a function with C language
> linkage with the same function name (ignoring the namespace names that
> qualify it) that appear in different namespace scopes refer to the same
> function."
>
> [basic.link]/10: "the types specified by all declarations referring to a
> given variable or function shall be identical"
>
> So the program is ill-formed because the same function is declared with
> two different types."

Ok, I'll modify Boost.WinAPI according to Peter's suggestion in a few days. I
intend to keep dllimport attributes on the functions though. If that still
breaks clang then I believe clang ticket should be reopened (or a MinGW ticket
should be filed).

Thanks Edward for communicating this through.

Peter Dimov

unread,
Jun 5, 2015, 7:52:40 AM6/5/15
to bo...@lists.boost.org
Andrey Semashev wrote:

> Also, windows.h defines a few offending macros, like min/max.

Not just a few; the entire API is macros that expand to the A or W version.

Edward Diener

unread,
Jun 5, 2015, 11:15:11 AM6/5/15
to bo...@lists.boost.org
On 6/5/2015 6:21 AM, Andrey Semashev wrote:
> On Friday 05 June 2015 05:45:18 Edward Diener wrote:
>>
>> The clang explanation, when asked to point to the C++ standard, is:
>>
>> "[dcl.link]/6: "At most one function with a particular name can have C
>> language linkage. Two declarations for a function with C language
>> linkage with the same function name (ignoring the namespace names that
>> qualify it) that appear in different namespace scopes refer to the same
>> function."
>>
>> [basic.link]/10: "the types specified by all declarations referring to a
>> given variable or function shall be identical"
>>
>> So the program is ill-formed because the same function is declared with
>> two different types."
>
> Ok, I'll modify Boost.WinAPI according to Peter's suggestion in a few days. I
> intend to keep dllimport attributes on the functions though.

That's fine. Just for you interest I asked on the mingw mailing list why
their implementation did not have dllimport while mingw64 does have
dllimport, and their response was:

"AFAIK, the dllimport attribute is not needed with C functions, but it
might be needed with variables and C++ classes. See the GCC manual
for the details."

From the GCC docs:

"For Microsoft Windows targets the use of the dllimport attribute on
functions is not necessary, but provides a small performance benefit by
eliminating a thunk in the DLL."

I quoted this in my reply to their reply but that was not going to
change their mind evidently as they did not respond further.

BTW maybe you can coordinate things so that fixing ticket
https://svn.boost.org/trac/boost/ticket/11338 is not going to be
duplicated effort.

> If that still
> breaks clang then I believe clang ticket should be reopened (or a MinGW ticket
> should be filed).

No problem. I can do that if necessary.

>
> Thanks Edward for communicating this through.

Clang, for all its pickiness, problems, and slow compiler speed, is
still a great compiler to use to check code so I do have an interest in
seeing that it works whenever possible with the Boost code I write or test.

Gavin Lambert

unread,
Jun 7, 2015, 7:13:01 PM6/7/15
to bo...@lists.boost.org
On 5/06/2015 20:31, Andrey Semashev wrote:
> On Friday 05 June 2015 19:04:51 Gavin Lambert wrote:
>>
>> What is the reason that Boost WinAPI redeclares the structure? Can it
>> be changed to just use the one from the Windows headers (perhaps via
>> typedef, if the internal typename is needed for compatibility)?
>>
>> (After writing the above, a cursory glance at the code suggests that it
>> does do that if BOOST_USE_WINDOWS_H is defined. So that changes the
>> question: under what conditions is that not defined?)
>
> The reason of Boost.WinAPI existence is that people don't want to include
> windows.h, especially in public headers. It is a heavy header that brings in
> most of SDK. It depends on predefined macros, so including it once defines the
> API users will be able to use; this is inconvenient for both Boost and its
> users. Also, windows.h defines a few offending macros, like min/max.

I'm not sure why this is a desirable goal. Any user application is
almost guaranteed to #include <windows.h> at some point -- it's the
platform header, you can't really accomplish anything of value without
doing so at some point, except in very trivial cases. (Just like any
non-trivial Linux app is likely to include one of the sys/ headers at
some point.)

And typically this is in precompiled headers such that the cost of doing
so is zero.

min/max issues are solved by using NOMINMAX or by using (std::min)(...)
or the long-winded BOOST_PREVENT_MACRO_EXPANSION (or something like
that; I forget the exact name, since I use the other approach).

Accidental conversion of method names from other top level macros (eg.
SendMessage -> SendMessageW) are somewhat undesirable but the Boost
naming conventions mean that this is never an issue for Boost code
anyway... and even if it were, given that the user application will most
likely be including windows.h then you'll actually be *causing* problems
by trying to avoid picking up the WinAPI name.

Peter Dimov

unread,
Jun 7, 2015, 7:21:29 PM6/7/15
to bo...@lists.boost.org
Gavin Lambert wrote:

> Any user application is almost guaranteed to #include <windows.h> at some
> point...

Not in every .cpp file. Any portable application isolates its <windows.h>
use to a few Windows-specific files, but even non-portable applications have
been known to do that. Not everyone appreciates if you #include <windows.h>
in a public header.

Andrey Semashev

unread,
Jun 7, 2015, 8:05:18 PM6/7/15
to bo...@lists.boost.org
On Monday 08 June 2015 11:12:19 Gavin Lambert wrote:
> On 5/06/2015 20:31, Andrey Semashev wrote:
> >
> > The reason of Boost.WinAPI existence is that people don't want to include
> > windows.h, especially in public headers. It is a heavy header that brings
> > in most of SDK. It depends on predefined macros, so including it once
> > defines the API users will be able to use; this is inconvenient for both
> > Boost and its users. Also, windows.h defines a few offending macros, like
> > min/max.
>
> I'm not sure why this is a desirable goal. Any user application is
> almost guaranteed to #include <windows.h> at some point -- it's the
> platform header, you can't really accomplish anything of value without
> doing so at some point, except in very trivial cases. (Just like any
> non-trivial Linux app is likely to include one of the sys/ headers at
> some point.)

By not including windows.h in Boost we let the user decide what features of
windows.h he wants to use and not depend on his choice. This is much less of a
problem with POSIX headers because they are more fine grained and do not
depend on predefined macros so much.
Reply all
Reply to author
Forward
0 new messages