Problem with std::pair has incomplete type

Get help for specific problems
Posts: 306
Joined: 7 Jan 2018

bgstack15

Hi Zenju, I would like to know if it would be a problem if for my builds, that I revert to the old logic used in FreeFileSync/Source/base/file_hiearchy.h, because of this compile error:
In file included from /usr/include/c++/11/bits/stl_algobase.h:64,
                 from /usr/include/c++/11/bits/char_traits.h:39,
                 from /usr/include/c++/11/string:40,
                 from /usr/include/c++/11/stdexcept:39,
                 from /usr/include/c++/11/system_error:41,
                 from /usr/include/c++/11/bits/std_mutex.h:39,
                 from /usr/include/c++/11/bits/atomic_wait.h:49,
                 from /usr/include/c++/11/bits/atomic_base.h:41,
                 from /usr/include/c++/11/atomic:41,
                 from ../../zen/globals.h:10,
                 from ../../zen/i18n.h:12,
                 from <command-line>:
/usr/include/c++/11/bits/stl_pair.h: In instantiation of 'struct std::pair<fff::FolderAttributes, fff::FolderContainer>':
/usr/include/c++/11/bits/stl_pair.h:218:11:   required from 'struct std::pair<const zen::Zbase<char>, std::pair<fff::FolderAttributes, fff::FolderContainer> >'
/usr/include/c++/11/ext/aligned_buffer.h:91:28:   required from 'struct __gnu_cxx::__aligned_buffer<std::pair<const zen::Zbase<char>, std::pair<fff::FolderAttributes, fff::FolderContainer> > >'
/usr/include/c++/11/bits/hashtable_policy.h:234:43:   required from 'struct std::__detail::_Hash_node_value_base<std::pair<const zen::Zbase<char>, std::pair<fff::FolderAttributes, fff::FolderContainer> > >'
/usr/include/c++/11/bits/hashtable_policy.h:268:12:   required from 'struct std::__detail::_Hash_node_value<std::pair<const zen::Zbase<char>, std::pair<fff::FolderAttributes, fff::FolderContainer> >, true>'
/usr/include/c++/11/bits/hashtable_policy.h:277:12:   required from 'struct std::__detail::_Hash_node<std::pair<const zen::Zbase<char>, std::pair<fff::FolderAttributes, fff::FolderContainer> >, true>'
/usr/include/c++/11/bits/hashtable_policy.h:1812:13:   required from 'struct std::__detail::_Hashtable_alloc<std::allocator<std::__detail::_Hash_node<std::pair<const zen::Zbase<char>, std::pair<fff::FolderAttributes, fff::FolderContainer> >, true> > >'
/usr/include/c++/11/bits/hashtable_policy.h:811:13:   required from 'struct std::__detail::_Insert_base<zen::Zbase<char>, std::pair<const zen::Zbase<char>, std::pair<fff::FolderAttributes, fff::FolderContainer> >, std::allocator<std::pair<const zen::Zbase<char>, std::pair<fff::FolderAttributes, fff::FolderContainer> > >, std::__detail::_Select1st, std::equal_to<zen::Zbase<char> >, std::hash<zen::Zbase<char> >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >'
/usr/include/c++/11/bits/hashtable_policy.h:1004:12:   required from 'struct std::__detail::_Insert<zen::Zbase<char>, std::pair<const zen::Zbase<char>, std::pair<fff::FolderAttributes, fff::FolderContainer> >, std::allocator<std::pair<const zen::Zbase<char>, std::pair<fff::FolderAttributes, fff::FolderContainer> > >, std::__detail::_Select1st, std::equal_to<zen::Zbase<char> >, std::hash<zen::Zbase<char> >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true>, false>'
/usr/include/c++/11/bits/hashtable.h:180:11:   required from 'class std::_Hashtable<zen::Zbase<char>, std::pair<const zen::Zbase<char>, std::pair<fff::FolderAttributes, fff::FolderContainer> >, std::allocator<std::pair<const zen::Zbase<char>, std::pair<fff::FolderAttributes, fff::FolderContainer> > >, std::__detail::_Select1st, std::equal_to<zen::Zbase<char> >, std::hash<zen::Zbase<char> >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >'
/usr/include/c++/11/bits/unordered_map.h:105:18:   required from 'class std::unordered_map<zen::Zbase<char>, std::pair<fff::FolderAttributes, fff::FolderContainer> >'
base/file_hierarchy.h:108:17:   required from here
/usr/include/c++/11/bits/stl_pair.h:218:11: error: 'std::pair<_T1, _T2>::second' has incomplete type
  218 |       _T2 second;                ///< The second member
      |           ^~~~~~
compilation terminated due to -Wfatal-errors.
make: *** [Makefile:132: /tmp/FreeFileSync_Make/ffs/src/application.cpp.o] Error 1
make: Leaving directory '/usr/src/freefilesync/11.21-1/FreeFileSync/Source'
It appears that the problem lies with being unordered_map used with std::pair (link to reddit thread).

I see that in the past, line 108 of file_hierarchy.h used std::map and not std::unordered_map. Could I switch back to that, and what would the caveats be?
User avatar
Site Admin
Posts: 7052
Joined: 9 Dec 2007

Zenju

Performance, basically, std::map has logarithmic lookup complexity, std::unordered_map constant. Best solution would be to use the latest GCC 12.1.
Posts: 3
Joined: 4 May 2022

zensubz

Thanks @bgstack15 for this, I could get FFS v11.21 compile based on your observations. I had to patch few files (patch attached). It does impact the GUI elements, in the sense, there is 'swapping' (pics attached). I hope there might be better workarounds, if you could kindly let us know. Thanks.

As @Zenju has advised, getting GCC 12.x is another nightmare for me...!
--- a/FreeFileSync/Source/base/db_file.cpp
+++ b/FreeFileSync/Source/base/db_file.cpp
@@ -642,7 +642,7 @@
 
     void process(const ContainerObject::FolderList& currentFolders, const Zstring& parentRelPath, InSyncFolder::FolderList& dbFolders)
     {
-        std::unordered_map<ZstringNorm, const FolderPair*> toPreserve;
+        std::map<ZstringNorm, const FolderPair*> toPreserve;
 
         for (const FolderPair& folder : currentFolders)
             if (!folder.isPairEmpty())
--- a/FreeFileSync/Source/base/db_file.h
+++ b/FreeFileSync/Source/base/db_file.h
@@ -67,9 +67,9 @@
     InSyncStatus status = DIR_STATUS_STRAW_MAN;
 
     //------------------------------------------------------------------
-    using FolderList  = std::unordered_map<ZstringNorm, InSyncFolder >; //
-    using FileList    = std::unordered_map<ZstringNorm, InSyncFile   >; // key: file name (ignoring Unicode normal forms)
-    using SymlinkList = std::unordered_map<ZstringNorm, InSyncSymlink>; //
+    using FolderList  = std::map<ZstringNorm, InSyncFolder >; //
+    using FileList    = std::map<ZstringNorm, InSyncFile   >; // key: file name (ignoring Unicode normal forms)
+    using SymlinkList = std::map<ZstringNorm, InSyncSymlink>; //
     //------------------------------------------------------------------
 
     FolderList  folders;
--- a/FreeFileSync/Source/base/file_hierarchy.h
+++ b/FreeFileSync/Source/base/file_hierarchy.h
@@ -7,12 +7,14 @@
 #ifndef FILE_HIERARCHY_H_257235289645296
 #define FILE_HIERARCHY_H_257235289645296
 
+#include <map>
 #include <string>
 #include <memory>
 #include <list>
 #include <functional>
 #include <unordered_set>
-#include <unordered_map>
+#include <zen/zstring.h>
+#include <zen/stl_tools.h>
 #include "structures.h"
 #include "path_filter.h"
 #include "../afs/abstract.h"
@@ -94,9 +96,9 @@
     //------------------------------------------------------------------
     //key: raw file name, without any (Unicode) normalization, preserving original upper-/lower-case
     //"Changing data [...] to NFC would cause interoperability problems. Always leave data as it is."
-    using FolderList  = std::unordered_map<Zstring, std::pair<FolderAttributes, FolderContainer>>;
-    using FileList    = std::unordered_map<Zstring, FileAttributes>;
-    using SymlinkList = std::unordered_map<Zstring, LinkAttributes>;
+    using FolderList  = std::map<Zstring, std::pair<FolderAttributes, FolderContainer>>;
+    using FileList    = std::map<Zstring, FileAttributes>;
+    using SymlinkList = std::map<Zstring, LinkAttributes>;
     //------------------------------------------------------------------
 
     FolderContainer() = default;
--- a/zen/json.h
+++ b/zen/json.h
@@ -41,7 +41,7 @@
 
     Type type = Type::null;
     std::string                                primVal; //for primitive types
-    std::unordered_map<std::string, JsonValue> objectVal; //"[...] most implementations of JSON libraries do not accept duplicate keys [...]" => fine!
+    std::map<std::string, JsonValue> objectVal; //"[...] most implementations of JSON libraries do not accept duplicate keys [...]" => fine!
     std::vector<JsonValue>                     arrayVal;
 };
 
Attachments
20220524-162454.jpg
20220524-162454.jpg (8.17 KiB) Viewed 1391 times
20220524-162450.jpg
20220524-162450.jpg (8.2 KiB) Viewed 1391 times
Posts: 306
Joined: 7 Jan 2018

bgstack15

Thanks for the patch for g++ < 12. Fedora 35 still has g++ 11 so I needed that. But Devuan Ceres has g++12 so I can skip the patch there.