[tex-live] [tlbuild] build failure: texk/dvisvgm/dvisvgm-0.8.7/src/FontEngine.cpp has some type mismatches when calling freetype API

Vladimir Volovich vvv at vsu.ru
Tue Jun 1 00:42:27 CEST 2010


"KB" == Karl Berry writes:

 KB> But your test is not nearly the same as the code at hand, so I
 KB> don't think we can conclude anything.

C++ seems to have much stricter type checking than C.

 KB> Are you saying you can't pass pointers from C++ code to extern "C"
 KB> code?

 KB> As far as I can tell, both the C++ and C code here are using
 KB> pointers to unsigned types.

apparently i was wrong in my quick reply.

this is a "minimal test case" derived from dvisvgm:

//=======================
namespace internal {
   template<unsigned BYTES>
   class ERROR_inttype_not_available
   {
      ERROR_inttype_not_available();
   };

   template<bool FIRST, typename A, typename B>
   struct select
   {
      typedef A T;
   };

   template<typename A, typename B>
   struct select<false, A, B>
   {
      typedef B T;
   };
}

// Retrieves a signed integer type with sizeof(T) == BYTES
template<unsigned BYTES, bool SIGNED>
struct int_t
{
   typedef typename internal::select<sizeof(signed char)       == BYTES, signed char,
           typename internal::select<sizeof(signed short)      == BYTES, signed short,
           typename internal::select<sizeof(signed int)        == BYTES, signed int,
           typename internal::select<sizeof(signed long)       == BYTES, signed long,
           typename internal::select<sizeof(signed long long)  == BYTES, signed long long,
           internal::ERROR_inttype_not_available<BYTES> >::T>::T>::T>::T>::T T;
};

// Retrieves an unsigned integer type with sizeof(T) == BYTES
template<unsigned BYTES>
struct int_t<BYTES, false>
{
   typedef typename internal::select<sizeof(unsigned char)      == BYTES, unsigned char,
           typename internal::select<sizeof(unsigned short)     == BYTES, unsigned short,
           typename internal::select<sizeof(unsigned int)       == BYTES, unsigned int,
           typename internal::select<sizeof(unsigned long)      == BYTES, unsigned long,
           typename internal::select<sizeof(unsigned long long) == BYTES, unsigned long long,
           internal::ERROR_inttype_not_available<BYTES> >::T>::T>::T>::T>::T T;
};

typedef int_t<4, false>::T UInt32;

extern "C" {
  extern void f_c(unsigned int *x);
}

void f_cpp(void) {
  UInt32 x;
  f_c(&x);
}
//=======================

which gives an error in xlC:

$ xlC -c test.cpp 
"test.cpp", line 52.7: 1540-0256 (S) A parameter of type "unsigned int *" cannot be initialized with an expression of type "int *".
"test.cpp", line 52.7: 1540-1205 (I) The error occurred while converting to parameter 1 of "f_c(unsigned int *)".

so xlC appears to be using the first template (with signed types) rather
than the second template (with unsigned types) when applying them to

typedef int_t<4, false>::T UInt32;

(indeed if i change "signed int" to "unsigned int" in the 1st template,
it compiles).

i don't know c++ enough to judge whether the xlC's behavior is wrong
when selecting which template to apply.

Best,
v.


More information about the tex-live mailing list