-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
[READY] Add explicit instantiation of string_id<T>::NULL_ID to make clang happy. #20946
[READY] Add explicit instantiation of string_id<T>::NULL_ID to make clang happy. #20946
Conversation
Awesome. Does this fix #17197 as well? |
I think so, to get the benefit I'll add some cleanup, thanks for asking.
|
After a lot more fiddling around, it turns out that
It looks like the intent is for the initialization of NULL_ID to be optional in order to allow individual specializations of the template to provide different strings. This arrangement was allowed because string_id::is_null() and string:id::string_id( const null_id_type & ) weren't often used, and the linker would discover if they were and throw an error. New versions of clang have started warning about this scenario regardless of whether the member is used or not, which I can't argue with. Also it seems like there are some visibility problems, the member needs to be initialized in every compilation unit where it is used, which probably means the initilization needs to happen in header files instead of in cpp files as is happening now. Two nice-to-haves:
|
The "simplest" thing sems to be to hoist the initialization of the respective NULL_ID instances to the header files for their classes, but this is really wordy and possibly fragile. It also prevents the use of forward declarations sometimes. I'm wondering if I can include the null string (if any) in an explicit template instantiation statement, then we can have the NULL_ID initialization happen in the body of string_id, and possibly restrict the verbosity of the instantiation. |
Know this is a WIP but can confirm that this makes Apple's LLVM happy 🙏 |
Thanks for the confirmation, put it in [WIP] because it fails to link with
the latest gcc:/
|
61a9551
to
f98c7bb
Compare
So... more context since this is turning out to be incredibly problematic to address. in src/string_id.h we have:
Then in various compilation units we have something like (this is src/harvest.cpp)
At other points we have references to NULL_ID. The result is the kind of warning in #18493:
I've tried various things to sort this out, but so far I haven't found a way to make both clang and gcc happy. Clang throws the above warning on solutions gcc is happy with, and the gcc linker complains about multiple template definition if I add the explicit instantiation declarations Clang suggests. This is the explicit declaration I'm using:
This is the explicit specialization:
|
f98c7bb
to
fe06466
Compare
Wow, just wow. This turned into a massive pain in the ass, but I finally have it sorted out. |
I moved some code from various headers to .cpp files, it didn't end up being necessary, but there should be as little code in headers as possible, so it's better as it is. |
fe06466
to
9d69a95
Compare
Getting this error after that merge: clang++ -DRELEASE -DMACOSX -DGIT_VERSION -DOSX_SDL2_LIBS -DTILES -DUSE_HOME_DIR -ffast-math -Os -Wall -Wextra -fsigned-char -Werror -stdlib=libc++ -std=c++11 -MMD -mmacosx-version-min=10.7 -D_THREAD_SAFE -I/usr/local/include/SDL2 -DSDL_SOUND -I/usr/local/include/SDL2 -D_THREAD_SAFE -I/usr/local/include -c src/mutation.cpp -o obj/tiles/mutation.o
src/mutation.cpp:568:22: error: instantiation of variable 'string_id<mutation_branch>::NULL_ID' required here, but no definition is available
[-Werror,-Wundefined-var-template]
return trait_id::NULL_ID;
^
src/string_id.h:146:35: note: forward declaration of template entity is here
static const string_id<T> NULL_ID;
^
src/mutation.cpp:568:22: note: add an explicit instantiation declaration to suppress this warning if 'string_id<mutation_branch>::NULL_ID' is explicitly
instantiated in another translation unit
return trait_id::NULL_ID;
^
1 error generated.
make: *** [obj/tiles/mutation.o] Error 1 macOS 10.12.4, compiled with Homebrew, compilation command was |
Booo >_<
probably in mutations.h |
3ba9942
to
00ad18e
Compare
Should be sorted out now. |
@kevingranade can confirm; successful build! |
Fixes #18493
Fixes #20915
Obsoletes #20935
Thanks to http://stackoverflow.com/questions/39420569/how-to-fix-a-purported-lack-of-an-explicit-instantiation-declaration-when-comp and fmtlib/fmt#318 for explaining how to address the issue