Porting code from GCC to msvc

Source: Internet
Author: User

Address: http://blog.csdn.net/ariesjzj/article/details/7881049

One of the difficulties in Porting a project's build system from GCC to msvc is that the source code uses GCC extension (http://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html), which can be given by adding the compilation option-pedantic. The second difficulty is that some Linux functions are not available in windows, or the implementation is slightly different. The third difficulty lies in the difference in the processing behavior selected by the two compilers in the same case. The following lists some common incompatibility and modification methods.

 

1. byte alignment)

The Byte alignment in GCC is as follows:

typedef struct foo { char a;int b;} __attribute__((packed)) foo;

Available in msvc:

#pragma pack(push, 1)typedef struct foo { char a;int b;} foo;#pragma pack(pop)  

Here 1 is the upper limit of the alignment value of the structure member. The latter GCC is also supported by extension, so both platforms can be compiled in this way.

 

Set the minimum alignment value in GCC:

typedef struct  A{int b;} __attribute__((aligned(32))) A;

In msvc:

typedef __declspec(align(32)) struct  A{int b;} A;

2. Code run before Main

Use _ attribute _ (constructor) in GCC, for example:

static void  __attribute__((constructor)) before(void) {printf("before\n");}

Available in msvc:

int before()  {      printf("%s\n", "before");      return 0;  }       #pragma data_seg(".CRT$XIU")   int (*f) () = before;#pragma data_seg()  

Or:

void foo(){printf("foo\n");}typedef void (__cdecl *PF)(void);#pragma section(".CRT$XCG", read)__declspec(allocate(".CRT$XCG")) PF f[] = {foo};

3. Case range

The range of values in the switch statement in GCC can be expressed...

switch (x) {case 0x03 ... 0x10:// ...break;...}

This usage can be written to the script to automatically convert (http://blog.csdn.net/ariesjzj/article/details/7848467 ).

 

4. Designated initializer

Only assign values to the specified member in the struct.

struct foo {int i; int j; };   struct foo f = {.j = 4};

Many projects compiled with GCC often use this method. For example, the system provides a unified set of interfaces for each device, but for a certain device, you only need to implement some interfaces, generally, only some members are assigned a value during registration. Add the struct variable name before the value assignment statement (add the string Ctrl + V before multiple rows in VI, select the row, I (uppercase I), and enter the unified prefix, ESC) put it in the initialization function, or fill in each member variable in the struct in the value assignment. If no member variable exists, it is assigned 0 or null.

 

For the structure of more members, it can only be automatically changed with the script, here is an example: http://blog.csdn.net/ariesjzj/article/details/7944005

 

5. Empty Array

GCC extension allows empty definition of an empty array. If an empty array is a header pointer of a variable-length member inside the struct, replace it with a single-element array. Sometimes an empty array is used for this ring declaration:

int (*f[])(void);void help() {    // use f[i]}int (*f[])(void) = {    ...    help,    ...}

Here, help () uses the function pointer array F, while the definition of F uses help (). To break this chicken-egg declaration structure, add help () before F declaration () statement:

void help();int (*f[])(void);void help() {    // use f[i]}int (*f[])(void) = {    ...    help,    ...}

6. Void * arithematic

In msvc, the void * variable arithmetic operation is not allowed. In GCC, the void * operation is in 1 byte, which is equivalent to unsigned char *. Therefore, the void * is declared as an unsigned char * or uint8_t * During msvc compilation, so that the original semantics is not changed.

 

7 arrays of Variable Length

GCC allows variables as the length of the array declaration. In this case, either define an array that is large enough or change it to an array that is dynamically allocated.

 

8. inline, _ inline __, _ inline

GCC knows all the above three keywords, but msvc only recognizes _ inline when processing c files. While the general use of GCC projects will generally use inline, compatibility considerations good will use _ inline _ (http://gcc.gnu.org/onlinedocs/gcc/Alternate-Keywords.html ). If the latter is used, it will be better to port it. For example, it can be defined in the shared header file:

 #ifdef _MSC_VER #define __inline__  __inline #endif

Or add-D _ inline __=__ inline to the compilation options. If the inline keyword is used in the original project, it is more troublesome because it may replace other strings with the inline name.

For forced inline, GCC has _ attribute _ (always_inline), while msvc has forceinline.

 

9 thread-Local Storage

GCC:

__thread int tls_i;

In msvc:

__declspec( thread ) int tls_i;

For more detailed documentation, see http://msdn.microsoft.com/en-us/library/6yh4a9k1.aspx and http://msdn.microsoft.com/en-us/library/2s9wt68x.aspx

 

10. # define contains # ifdef or # pragma

If # ifdef is included in the macro definition in msvc, # ifdef is not parsed first. For example:

#define DEF(str1)  str1char * a = DEF("a",#ifdef _WIN32"win32"#else"not win32" #endif"end\n");

GCC is explained first # ifdef, msvc will explain first # define, extended to "A" # ifdef 1 "Win32" # else "not Win32" # endif "End \ n ", then the compilation fails. Add/E to msvc to view the macro expansion result.
In the same way # define contains # pragma, then you need to change # pragma to _ Pragma (http://msdn.microsoft.com/en-us/library/d9x1s805.aspx)

 

11. Get the caller address

In GCC, _ builtin_return_address (0) can obtain the address of the subfunction called by the caller. It is accurate to the address of the command to be executed after the caller returns the result.

_ Returnaddress in msvc can achieve the same purpose.

 

12. msvc has corresponding functions, but the function names are different.

Just redefine the line, such:

#ifdef _MSC_VER#define strtoll _strtoi64#define strtoull _strtoui64#define snprintf _snprintf#define popen   _popen#define pclose  _pclose#define strcasecmp _stricmp#define strncasecmp _strnicmp#endif

13. functions not provided in msvc

Such as RINT, remainder, trunc, gettimeofday, and va_copy. These mingw GCC functions are implemented through the build-in function or static link, without relying on msvcrt. These functions can only be copied, for example:

#ifdef _MSC_VER__inline int gettimeofday(struct timeval *tp, void *tzp){    time_t clock;    struct tm tm;    SYSTEMTIME wtm;    GetLocalTime(&wtm);    tm.tm_year     = wtm.wYear - 1900;    tm.tm_mon     = wtm.wMonth - 1;    tm.tm_mday     = wtm.wDay;    tm.tm_hour     = wtm.wHour;    tm.tm_min     = wtm.wMinute;    tm.tm_sec     = wtm.wSecond;    tm. tm_isdst    = -1;    clock = mktime(&tm);    tp->tv_sec = clock;    tp->tv_usec = wtm.wMilliseconds * 1000;    return (0);}double trunc(double x){    if (x > 0) return floor(x);    else return ceil(x);}intfesetround (int round){  unsigned short int cw;  if ((round & ~0xc00) != 0)    /* ROUND is no valid rounding mode.  */    return 1;  __asm { fnstcw cw}  cw &= ~0xc00;  cw |= round;  __asm {fldcw cw}  return 0;}__inline double rint(double dbl){    _asm    {        fld dbl        frndint    }}__inline long double rintl(long double x){    _asm    {        fld x         frndint    }}double remainder(double x, double y){    double i = rint(x/y);    return x - i * y;}#ifndef va_copy#define va_copy(dst, src) ((dst) = (src))#endif#endif

Note the nuances of similar functions, which are implemented by strictly following man or document, such as fmod and remainder. The difference is that one operator is rounded to 0, and the other is rounded to the nearest node.
In addition, libgw32c for Windows provides some gnu c functions Windows implementation http://gnuwin32.sourceforge.net/packages/libgw32c.htm

 

14 different platforms have the same function declaration but different behavior

Some functions are provided by both platforms, and the declaration is the same, but the behavior is different. This usually leads to a strange error during running.

For example, if the _ creat function is used, mingw GCC compiles creat ("a.txt", 0666) and runs OK. If MSC is compiled, crash is used, because the second parameter is interpreted differently on the two platforms. In addition, for example, _ lseeki64, msvc always returns an incorrect value, leading to a file read error.

 

15 system const

Some constants are defined differently in both Windows and Linux. In this case, they cannot be copied simply, such as s_ifmt and s_ifdir.

 

16 global register variable

Some places place a frequently used structure in fixed registers for optimization, such:

Int a asm ("EBP ")

There is no uniform method, and case-by-case processing is required. If code refactoring is troublesome, put the variable in the EBP before using the structure, and restore the EBP after it is used up.

 

17 calling convention

Add:

_ Attribute _ (regparm (3 )))

Parameters are transmitted using registers eax, EDX, and ECx. Similar to fastcall, but fastcall in msvc is transmitted using EDX and ECx, which is slightly different. The method to compare the insurance points is to change both the called end and the called end to the stack parameter.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.