cvisual-c++compiler-errorsint128

Multiple VC compile errors


I'm using VC++ to write a 128-bit integer "class" in C (wrapped the header in extern "C" block), however, during routine builds to check for errors, I encountered many after adding this function:

/* Negate (2s compliment NOT) a 128-bit integer */
INT128_INLINE void int128_neg(int128_t *ret, int128_t arg)
{
    /* 2s compliment negation is equivalent to ((~value) + 1) */

    int128_t one;
    int128_from_i8(&one, 1);

    int128_t inv;
    int128_inv(&inv, arg);

    int128_add(ret, one, inv);
}

Essentially, if it's not clear enough, it finds the negative (-x) of a given int128_t. Here is the int128_t structure:

/* Work at the byte level to work around endianess crap */
/* (speaking of which, this is big endian, at least is should be) */
#pragma pack(1)
struct _int128_t
{
    /* SIGN BIT: 0xxxxxxx = positive; 1xxxxxxx = negative */
    uint8_t byte01; /* MSB */
    uint8_t byte02;
    uint8_t byte03;
    uint8_t byte04;
    uint8_t byte05;
    uint8_t byte06;
    uint8_t byte07;
    uint8_t byte08;
    uint8_t byte09;
    uint8_t byte10;
    uint8_t byte11;
    uint8_t byte12;
    uint8_t byte13;
    uint8_t byte14;
    uint8_t byte15;
    uint8_t byte16; /* LSB */
};

/* A 128-bit integer structure and functions written in pure C99 code :) */
typedef struct _int128_t int128_t;

and the function prototypes:

/* Invert (~) a 128-bit integer */
INT128_INLINE void int128_inv(int128_t *ret, int128_t arg) { ... }

/* Add two 128-bit integers together */
INT128_INLINE void int128_add(int128_t *ret, int128_t lhs, int128_t rhs) { ... }

and INT128_INLINE (obviously the one that sets it to __inline is used):

/* MC++ requires `__inline`*/
#ifdef _MSC_VER
#  define INT128_INLINE __inline
#else
   /* use standard inline */
#  define INT128_INLINE inline
#endif

Now, the errors I am receiving with the function are:

Error   24  error C2275: 'int128_t' : illegal use of this type as an expression d:\libplist\libplist\include\int128.h   313 1   libplist
Error   25  error C2146: syntax error : missing ';' before identifier 'inv' d:\libplist\libplist\include\int128.h   313 1   libplist
Error   26  error C2065: 'inv' : undeclared identifier  d:\libplist\libplist\include\int128.h   313 1   libplist
Error   28  error C2065: 'inv' : undeclared identifier  d:\libplist\libplist\include\int128.h   314 1   libplist
Error   29  error C2065: 'inv' : undeclared identifier  d:\libplist\libplist\include\int128.h   316 1   libplist
Error   30  error C2440: 'function' : cannot convert from 'int' to 'int128_t'   d:\libplist\libplist\include\int128.h   316 1   libplist
Error   32  error C2371: 'int128_inv' : redefinition; different basic types d:\libplist\libplist\include\int128.h   324 1   libplist

and before you ask, line 313 is the int128_t inv;. And also, libplist is an Apple PList library I am working on to work that uses libxml2 with the iTunes database (C:\Users\{YOU}\My Music\iTunes\iTunes Library.xml)

I tried rewriting the function to be sure it wasn't some weird Unicode crap (like people do to troll with the R2L char), but it didn't help. I tried doing int128_t inv = *ret;, but that just gives:

Error   27  error C2440: '=' : cannot convert from 'int128_t' to 'int'  d:\libplist\libplist\include\int128.h   313 1   libplist

Solution

  • int128_t one;
    int128_from_i8(&one, 1);
    
    int128_t inv;
    int128_inv(&inv, arg);
    

    This is not valid C89 code because C89 requires that all variables are declared at the top of a function, and Visual C only supports C89. Declarations must appear before statements in a function. So, if you're truly using the C compiler (and not the C++ compiler), this would cause errors. What you should be doing instead is:

    int128_t one;
    int128_t inv;
    
    int128_from_i8(&one, 1);
    int128_inv(&inv, arg);
    

    Also, this comment is incorrect:

    /* A 128-bit integer structure and functions written in pure C99 code :) */
    

    If you're using Visual C, it's C89, not C99, for the aforementioned reason. Microsoft's said that they will never support any C standard later than C89 because they don't feel it's worth the effort and that everyone should be using C++ or C# instead. I don't like it, but I can't do anything about it; so, whatever.