Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

warning C4910: '__declspec(dllexport)' and 'extern' are incompatible on an explicit instantiation #2228

Closed
moiwi opened this issue Apr 12, 2021 · 11 comments · Fixed by #2229
Closed

Comments

@moiwi
Copy link
Contributor

moiwi commented Apr 12, 2021

Compiling format.h with FMT_EXPORT defined gives the warning

format.h(998,71): warning C4910: 'fmt::v7::detail::basic_data<void>': '__declspec(dllexport)' and 'extern' are incompatible on an explicit instantiation (compiling source file os.cc)

with Visual Studio 2019.
Why was

#ifndef FMT_EXPORTED

#endif

removed?

@vitaut
Copy link
Contributor

vitaut commented Apr 12, 2021

It was removed in #2220 because of clang warnings. It seems that MSVC and clang handle dllexport in incompatible ways.

@vitaut
Copy link
Contributor

vitaut commented Apr 12, 2021

We might need both FMT_INSTANTIATION_DECL_API and FMT_INSTANTIATION_DEF_API defined based on the compiler (sigh).

denchat added a commit to denchat/fmt that referenced this issue Apr 13, 2021
This should fix fmtlib#2228

To fix difference dllexport requirements
msvc:  dllexport at template instantiation definition in format.cc
clang: dllexport at template instantiation declaration (extern template) in format.h
@denchat
Copy link
Contributor

denchat commented Apr 13, 2021

I'm trying to fix this at #2229 .
However I'm not sure that...

#ifndef FMT_EXPORTED
extern template struct
#endif

is also required by msvc.

I don't have msvc, please report back.

@moiwi
Copy link
Contributor Author

moiwi commented Apr 13, 2021

It seems

#ifndef FMT_EXPORTED

#endif

is needed for MSVC. Without I still get ehe same warning

'__declspec(dllexport)' and 'extern' are incompatible on an explicit instantiation

@denchat
Copy link
Contributor

denchat commented Apr 13, 2021

Okey, I wrapped it up.

However, I've been thinking that msvc should never has seen extern template together with dllexport in the 1st place.
The preprocessor is supposed to behave like the previous one on msvc!?
That's odd or maybe I might have missed out something.

Please check again.

@moiwi
Copy link
Contributor Author

moiwi commented Apr 13, 2021

#2229 fixes my problem.
Without "#ifndef FMT_EXPORTED" the preprocessor output is

template <typename T = void> struct __declspec(dllexport) basic_data {
  static const uint64_t powers_of_10_64[];
  //...
  static const uint64_t zero_or_powers_of_10_64[];
};
//...
extern template struct  basic_data<void>;

which results in the mentioned compiler warning.

@vitaut
Copy link
Contributor

vitaut commented Apr 16, 2021

Thinking more of it, basic_data doesn't seem to need dllexport at all. At least I was able to build fmt dll with it removed (8bc4550) and the tests work.

@vitaut
Copy link
Contributor

vitaut commented Apr 16, 2021

@moiwi, @denchat, does 8bc4550 work for you?

@moiwi
Copy link
Contributor Author

moiwi commented Apr 16, 2021

No, it doesn't work for me (with MSVC 2019).
I still get the line
template <typename T = void> struct FMT_EXTERN_TEMPLATE_API basic_data {
(which gets preprocessed to
template <typename T = void> struct __declspec(dllexport) basic_data {
) colliding with
FMT_EXTERN template struct basic_data<void>;
(which gets preprocessed to
extern template struct basic_data<void>;
)

It does however work if I remove "FMT_EXTERN_TEMPLATE_API" like that:
template <typename T = void> struct /*FMT_EXTERN_TEMPLATE_API*/ basic_data {

@vitaut
Copy link
Contributor

vitaut commented Apr 16, 2021

OK, let's go with #2229 then. Thanks for testing.

vitaut pushed a commit that referenced this issue Apr 16, 2021
* add FMT_INSTANTIATION_DEF_API for msvc

This should fix #2228

To fix difference dllexport requirements
msvc:  dllexport at template instantiation definition in format.cc
clang: dllexport at template instantiation declaration (extern template) in format.h
@denchat
Copy link
Contributor

denchat commented Apr 17, 2021

#2241

The extern template's game is quite a mess between camps!?
Clang: I don't like forward declaration of entity.
MSVC: I don't like extern template on members.

Sigh.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants