Linux port
The company who employs me has decided to port parts of our application to Linux. At a first shot we will use WSL and Visual Studio but issues are not over:
- CMake is the lingua franca of generating cross platform build scripts. CMake is a beast of itself however and not sure why this got so popular.
- WSL keeps sometimes its old configuration and source files. It seems that when the source files are read only they are read only on the target WSL system as well. If you edit a file afterwards the update of this file will fail so one won't see their changes. Either make the source files not read only beforehand or clean all files and directories on the WSL host and then start fresh again. Alternatively make the source files writable on Linux through chmod.
- MSVC uses __declspec(dllexport) to export functions from DLL's; GCC doesn't have that.
- MSVC is pushing security enhanced versions of the CRT through its code analyzer. According to cppreference these functions are standardized albeit as extension (i.e. Annex K of C11). Unfortunately glibc has not implemented them; partially because some dubious reasoning. The API isn't perfect and there are pre-exisiting bounds checking crt but still it's standardized and some people (we) use them. So one ends up writing Windows and Linux specific code even in a layer which supposed to be platform independent.
- Many of the MSVC C API is Windows specific (e.g. _splitpath; _makepath; _tchdir). Using C alone on Windows platform may therefore still not platform independent.
- Warning suppression's in pre-compiled header in GCC are ignored in code. This is quite unhandy; especially since some suppression's one want to apply globally to all sources and are therefore are primary candidate to put in pre-compiled header. I have filed a bug 123287 report and it's stated that this has been solved for GCC 15.x.
- On Windows wchar_t are 2 bytes and represent UCS-2 or UTF-16. On Linux wchar_t it is 4 bytes and probably represents UTF-32. To be compatible with existing persistence storage we had to use char16_t on certain places in the code. Unfortunately it seems that some character code conversion facilities are deprecated so this solution will not hold out for long.
- std::basic_ifstream and std::basic_ofstream don't accept std::wstring as function name on Linux. This seems to be a MSVC extension so change code to use std::filesystem::path which is a conformance improvement.
- __FUNCTION__ is an extension which both MSVC and GCC understand. On GCC it is not a macro so prepending it with 'L' to get the wide character variant does not work. It also only gives the function name without class in case member function which makes in unattractive. So specific MSVC and GCC code is needed. There is a standard: __func__. However again it only gives the function name. source_location is another alternative but this gives too much information for the function name.
- std::prev and std::advance with negative offset on GCC increment the iterator in case it's an input- or forward iterator. This lead to a crash with 'std::prev(umap.cend())' since on GCC std::unordered_map iterators are of forward iterator category type while on MSVC they are bidirectional. Preferably a compile time error was issues. Also using std::views::transform can result in an input iterator category which would fail then with std::prev. See bug 122224.
- no leading zero mask in date time (e.g. the'#' in '%#d') is a MSVC extension. Resolution: write ourselves.
- swprintf requires '%ls' for wchar_t arrays. This is unfortunate for writing char / wchar_t agnostic code.
GCC might still contain some basic bugs. The warning about #pragma once in main file (when building a pre-compiled header) is only solved in version 14.