This article describes some of the difficulties we encountered when trying to adapt one of our old Windows-only projects (plugin for MT4 server) to cross-compilation under Linux (CI, static analysis, auto-tests and other buzz words). More precisely, the code included a number of constructs that were quietly eaten by MSVC, but categorically refused to be compiled using mingw / gcc.
Under the cat 7 of the most common code examples that will be compiled by MSVC, but will not be with gcc, and ways to treat it.
The purpose of the article is not to say that a compiler is better than others, but to point out some problems that may arise when adapting the code to other compilers (especially if only MSVC was used before). Also, some (if not all) elements of behavior can be reduced to one, if you tweak the compilation flags, but it's better to fix the code (at least with sed), right?
If you are a novice trader, then we suggest you read here .
We have a medium-sized project (about 15k SLOC excluding libraries), which uses CMake with almost default compilation flags. MSVC uses 14 versions, and mingw-gcc - 6.3.
Inside our project there are several methods that should be called as C methods in order for the plugin to be recognized by the server. The following constructions were used in the original code:
__declspec(dllexport) void SomeMethod() {}
When compiling gcc, the function name was decorated, which meant that the server did not define the method in the plugin. More correct (working) solution:
extern "C" __declspec(dllexport) void SomeMethod() {}
The difference in the separators in the paths on different systems also leads to errors at the compilation stage. Code
#include "directory\\include.h"
will refuse to compile under Linux / gcc, although there will be no problems under Windows / MSVC. This is not entirely a mistake, but it should be noted that for ease of portability, it is better to use the usual slash, since it is perceived by most systems . There is also another problem with the paths ...
As you probably know, the paths some/path
and SoMe/pATh
in Windows do not differ, but this is not so in some other systems, which led to errors if the programmer specified the path in the header file without case sensitivity. For example:
#include <Winsock2.h>
will generate an error with gcc under Linux, because the specified file will simply not be found. A similar problem is also observed with library names, for example, Ws2_32
versus ws2_32
.
The project actively uses QuickFIX , which is supposed to be compiled and run under different systems. The current version of QuickFIX uses the following constructs:
#ifndef _MSC_VER #include <unistd.h> #endif
Don't do that. When using mingw, _MSC_VER
not defined; instead, it is more correct to check _WIN32
to determine the target platform, and _MSC_VER
use only if you want to include MSVC-specific code.
Code
class SomeClass { virtual void someMethod() = NULL; };
when trying to compile gcc will happily say
invalid pure specifier (only "= 0" is allowed)
but will not cause errors in MSVC. The reason is simple: gcc opens the NULL
macro not at 0, but at __null
(which, in general, is not prohibited at all). Solution: obviously, stop using NULL
to specify pure virtual methods and use = 0
.
Code
class SomeClass { SomeClass::SomeClass() {}; };
when using gcc will issue
extra qualification 'SomeClass ::' on member 'SomeClass'
The correct answer, obviously, should not contain SomeClass::
. In general, in the draft standard C ++ 14 (paragraph 8.3) it is written that:
The name of the qualifier refers to
Code written using the clipboard interface
void someMethod() { SomeClass; SomeClass class; }
contains an error that is ignored by MSVC, but will cause an error at compile time for gcc:
declaration does not declare anything
I'm not sure which behavior is correct here, and MSVC probably just cuts out an unused line without giving any signals.
Most of the errors listed by me are obviously corrected quite easily without reading this article, guided solely by the compiler’s comments. However, it vividly illustrates the difference between the “two worlds” in the perception of your source code, and what may be natural for you is not at all when changing the compiler.
Source: https://habr.com/ru/post/324512/
All Articles