Watch, Follow, &
Connect with Us

Please visit our new home
community.embarcadero.com.


Welcome, Guest
Guest Settings
Help

Thread: CBXE7 - IdCompressorZLib1->CompressStream() Android platform compile issues


This question is answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 2 - Last Post: Mar 31, 2015 2:19 AM Last Post By: GAI CHEW KAI
GAI CHEW KAI

Posts: 117
Registered: 7/25/14
CBXE7 - IdCompressorZLib1->CompressStream() Android platform compile issues  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 29, 2015 8:27 PM
I am using Embarcadero® C++Builder XE7 Version 21.0.17017.3725

IdCompressorZLib1->CompressStream( si, // System::Classes::TStream* AInStream,
master, // System::Classes::TStream* AOutStream,
1, // const Idzlibcompressorbase::TIdCompressionLevel ALevel,
15+16, // const int AWindowBits, add 16 to get gzip format
8, // const int AMemLevel, see note below
0 ); // const int AStrategy);

While trying to compile the instruction above for Android platform, the compiler reported error messages such as:

[bccaarm Error] oMain.cpp(596): no viable conversion from 'int' to 'Idzlibcompressorbase::TIdCompressionLevel'
IdZLibCompressorBase.hpp(27): candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const Idzlibcompressorbase::TIdCompressionLevel &' for 1st argument;
IdZLibCompressorBase.hpp(27): candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to 'Idzlibcompressorbase::TIdCompressionLevel &&' for 1st argument;
IdCompressorZLib.hpp(43): passing argument to parameter 'ALevel' here

Please advise.
Remy Lebeau (Te...


Posts: 8,839
Registered: 12/23/01
Re: CBXE7 - IdCompressorZLib1->CompressStream() Android platform compileissues [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 29, 2015 9:57 PM   in response to: GAI CHEW KAI in response to: GAI CHEW KAI
GAI wrote:

While trying to compile the instruction above for Android platform,
the compiler reported error messages such as:

[bccaarm Error] oMain.cpp(596): no viable conversion from 'int' to
'Idzlibcompressorbase::TIdCompressionLevel'

Two words - strong aliasing.

The third parameter of CompressStream() is a TIdCompressionLevel, which is
declared as follows in IdZLibCompressorBase.hpp:

_DECLARE_ARITH_TYPE_ALIAS(System::Int8, TIdCompressionLevel);


In C++ for Android and iOS, _DECLARE_ARITH_TYPE_ALIAS() is implemented as
follows in sysmac.h:

    // Earlier versions of Delphi mapped built-in types such as NativeInt/NativeUInt
    // ByteBool/WordBool/LongBool to C++ built-in types. But that prevented 
Delphi
    // code from overloading on, say, NativeInt and Integer (they both had 
to mangle
    // to 'int'). Newer versions of Delphi mangle these types as strong aliases.
    // To be compatible with the change, C++ will also create strong aliases.
    // This, though, comes at a cost: to avoid ambiguity, conversions must 
be explicit.
    // For example:
    //      NativeInt ni = 100;                  // Error
    //      NativeInt ni = NativeInt(100);       // OK
    //      System::GetMemory(0x100);            // Error
    //      System::GetMemory(NativeInt(0x100)); // OK
    template <typename BASE_T, typename ALIAS_T>
    class AliasT
    {
    protected:
      typedef AliasT<BASE_T, ALIAS_T> AliasType;
      AliasT() : data(BASE_T())
      {}
#ifdef __clang__
      constexpr
#endif
      explicit AliasT(const BASE_T &p) : data(p)
      {}
    public:
      // RLebeau: omitting a bunch of operator declarains for brevity...
    private:
      BASE_T data;
      AliasT& operator=(const BASE_T& rhs);
    };
}
 
#if defined(_DELPHI_NEXTGEN) && !defined(_Windows)
 
#define _DECLARE_ARITH_TYPE_ALIAS(Base, Alias)        \
  class Alias : public System::AliasT<Base, Alias> {  \
  public:                                             \
    Alias() : AliasType()                             \
    {}                                                \
    constexpr explicit Alias(Base i) : AliasType(i)   \
    {}                                                \
  private:                                            \
    Alias& operator=(const Base &rhs);                \
  };
 
...

As you can see, there is no constructor available for TIdCompressionLevel
that will implicitly accept an 'int' as input, it will only accept a System::Int8
as input, and only if the constructor is called explicitly. Hence the error
you are seeing - your code is trying to perform an implicit conversion that
is not allowed. As stated in the comments:

    // To be compatible with the change, C++ will also create strong aliases.
    // This, though, comes at a cost: to avoid ambiguity, conversions must 
be explicit.


So you need to change this portion of your code:

1, // const Idzlibcompressorbase::TIdCompressionLevel ALevel,


To this instead:

TIdCompressionLevel(1), // const Idzlibcompressorbase::TIdCompressionLevel 
ALevel,


--
Remy Lebeau (TeamB)
GAI CHEW KAI

Posts: 117
Registered: 7/25/14
Re: CBXE7 - IdCompressorZLib1->CompressStream() Android platform compileissues [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 31, 2015 2:19 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Thanks again, Remy.
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02