- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am in the process of updating a template library I made several years ago. The purpose of the update was more as an experiment in using variadic templates. The prior template library was not variadic, the updated version is.
Note, I realize that I am still debugging the templates.
The templates are used in files inside a static library file (a handful of .objs).
Then I have a test program that runs through permutations of template arguments.
The library builds with warnings of duplicate functions (due to different sources expanding the same template).
These are warning (should be hushed up).
The test program compiles fine (no warnings, probably because I've #if 0'd all tests but the first two).
The problem comes in with the Link phase of linking the app against the library. In this case, the duplicate entries cause an error.
I thought (and my prior experience was) that template expanded code, when identical, was permitted to have a pass at duplicate functions.
1>------ Rebuild All started: Project: QuickThread, Configuration: Debug x64 ------ 1> Performing Custom Build Tools ... 1>parallel_pipeline.obj : : warning LNK4006: "void __cdecl qt::qt_unwrap_fn_args(struct qt::unwrap_struct_t<void (__cdecl*)(void)> *)" (?qt_unwrap_fn_args@qt@@YAXPEAU?$unwrap_struct_t@P6AXXZ@1@@Z) already defined in QuickThread.obj; second definition ignored 1>parallel_manifold.obj : : warning LNK4006: "void __cdecl qt::qt_unwrap_fn_args(struct qt::unwrap_struct_t<void (__cdecl*)(void)> *)" (?qt_unwrap_fn_args@qt@@YAXPEAU?$unwrap_struct_t@P6AXXZ@1@@Z) already defined in QuickThread.obj; second definition ignored 1>parallel_list.obj : : warning LNK4006: "void __cdecl qt::qt_unwrap_fn_args(struct qt::unwrap_struct_t<void (__cdecl*)(void)> *)" (?qt_unwrap_fn_args@qt@@YAXPEAU?$unwrap_struct_t@P6AXXZ@1@@Z) already defined in QuickThread.obj; second definition ignored 1>parallel_allocator.obj : : warning LNK4006: "void __cdecl qt::qt_unwrap_fn_args(struct qt::unwrap_struct_t<void (__cdecl*)(void)> *)" (?qt_unwrap_fn_args@qt@@YAXPEAU?$unwrap_struct_t@P6AXXZ@1@@Z) already defined in QuickThread.obj; second definition ignored 1> QuickThread.vcxproj -> C:\QuickThread\QuickThread_v4\x64\Debug\QuickThread.lib 2>------ Rebuild All started: Project: TemplateTestSuite, Configuration: Debug x64 ------ 2> stdafx.cpp 2> TemplateTestSuite.cpp ... 2>QuickThread.lib(QuickThread.obj) : error LNK2005: "void __cdecl qt::qt_unwrap_fn_args(struct qt::unwrap_struct_t<void (__cdecl*)(void)> *)" (?qt_unwrap_fn_args@qt@@YAXPEAU?$unwrap_struct_t@P6AXXZ@1@@Z) already defined in TemplateTestSuite.obj 2>QuickThread.lib(parallel_allocator.obj) : error LNK2005: "void __cdecl qt::qt_unwrap_fn_args(struct qt::unwrap_struct_t<void (__cdecl*)(void)> *)" (?qt_unwrap_fn_args@qt@@YAXPEAU?$unwrap_struct_t@P6AXXZ@1@@Z) already defined in TemplateTestSuite.obj ... 2>C:\QuickThread\QuickThread_v4\x64\Debug\TemplateTestSuite.exe : fatal error LNK1169: one or more multiply defined symbols found ========== Rebuild All: 1 succeeded, 1 failed, 0 skipped ==========
Using VS 2013 with PS 2016 Update 2
Is there a linker option to have it check the duplicately named functions for same content, then ignore the second one?
Jim Dempsey
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I found a poor work around. That is to force the function expansions to be inline. This seems somewhat wasteful on memory to me.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This might be useful: https://msdn.microsoft.com/en-us/library/by56e477.aspx
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Nice article, but it does not fit my case.
The problem is some of the included .obj files within the library use a few instantiations of the templates. IOW require specific expansions.
By structuring the template in the code section of the files in the library as extern, this would indeed exclude those expansions from the library...
... however, this then requires the user code to expand the templates using <ArgT ...> unknown to it and hiding inside the library.
It would be klutzy to provide a .lib file plus a handful of .obj files, with which the user then figures out which ones to tack onto their build.
One also could use namespace to isolate the functions, but then you have an issue of code bloat, and/or versioning issues.
The best way would be for the linker to examine the .obj for duplicate named functions, and if identical, then either elide the extra instantiations or keep quiet (or with warning) continue with one chosen, and the others probably occupying memory. An implementation issue.
Back in the early days of C++ the linker would silently remove identical named member functions generated in different source files. I do not know what has changed now. In my case the affected codes are not member functions. i.e. they are program scoped functions.
Jim Dempsey

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page