Board index » cppbuilder » Cannot convert 'const int *' to 'const ctype_base::mask *'

Cannot convert 'const int *' to 'const ctype_base::mask *'


2005-08-19 02:58:19 AM
cppbuilder84
bcc32 cannot compile a file that I have. There is this line in the code
(qnamespace.h) followed by some other macros that produce the same problem.
//Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::MouseButtons) expands to (and another
inline function)
inline QFlags<Qt::MouseButtons::enum_type>
operator|(Qt::MouseButtons::enum_type f1, Qt::MouseButtons::enum_type f2) {
return QFlags<Qt::MouseButtons::enum_type>(f1) | f2;
}
If I remove these lines all compiles but with these lines the compiler
stops with the error.
Quote
Error E2034 C:\Borland\CBuilderX\include\stl/_ctype.h 124: Cannot
convert 'const int *' to 'const ctype_base::mask *' in function
ctype<char>::classic_table()
The example code looks very simple:
--------------------------
#include "qnamespace.h"
#include <iterator>
--------------------------
Each line for itself does not show the compiler error (bug?). But if I
include both files the bcc32.exe stops with an error. MSVC and gcc 3
compiler compile this file without any error.
Any hint/idea to solve this error?
The example with all required header files (4 headers) is available in
b.p.attachment.
MSVC output:
cl /nologo /c /IQtCore test.cpp
test.cpp
BCC32 output:
bcc32 -q -c -Q -IQtCore test.cpp
test.cpp:
Error E2034 C:\Borland\CBuilderX\include\stl/_ctype.h 124: Cannot convert
'const int *' to 'const ctype_base::mask *' in function
ctype<char>::classic_table()
+ Full parser context
+ test.cpp, line 3: #include C:\Borland\CBuilderX\include\iterator.h
+ C:\Borland\CBuilderX\include\iterator.h, line 18: #include
C:\Borland\CBuilderX\include\stlport\iterator
+ C:\Borland\CBuilderX\include\stlport\iterator, line 43: #include
C:\Borland\CBuilderX\include\stl/_stream_iterator.h
+ C:\Borland\CBuilderX\include\stl/_stream_iterator.h, line 57: #include
C:\Borland\CBuilderX\include\stl/_istream.h
+ C:\Borland\CBuilderX\include\stl/_istream.h, line 27: #include
C:\Borland\CBuilderX\include\stl/_ios.h
+ C:\Borland\CBuilderX\include\stl/_ios.h, line 27: #include
C:\Borland\CBuilderX\include\stl/_ctype.h
+ C:\Borland\CBuilderX\include\stl/_ctype.h, line 35: namespace _STL +
C:\Borland\CBuilderX\include\stl/_ctype.h, line 62: class ctype<char>
+ C:\Borland\CBuilderX\include\stl/_ctype.h, line 151: decision to
instantiate: const ctype_base::mask * ctype<char>::classic_table()
+ --- Resetting parser context for instantiation...
*** 1 errors in Compile ***
--
Regards,
Andreas Hausladen
 
 

Re:Cannot convert 'const int *' to 'const ctype_base::mask *'

Here a very simple code showing the same effect:
--------------------------------------------------------
enum MyEnum {
MyEnumNull = 0,
MyEnumOne = 1,
MyEnumOneTwo = 2
};
#if 1 // set to 0 and the code compiles without errors
inline // with and without
int // this can be everything (class, struct, simple type, pointer)
operator|(MyEnum, MyEnum) { return 0; }
#endif
#include <iterator>
--------------------------------------------------------
--
Regards,
Andreas Hausladen
 

Re:Cannot convert 'const int *' to 'const ctype_base::mask *'

bccx (Borland C++ Compiler 6.0 Preview) compiles the above example without
error. So it must be a compiler bug. And I need a way to solve this. Any
ideas?
--
Regards,
Andreas Hausladen
 

{smallsort}

Re:Cannot convert 'const int *' to 'const ctype_base::mask *'

"Andreas Hausladen" < XXXX@XXXXX.COM >writes:
Quote
Here a very simple code showing the same effect:

--------------------------------------------------------
enum MyEnum {
MyEnumNull = 0,
MyEnumOne = 1,
MyEnumOneTwo = 2
};

#if 1 // set to 0 and the code compiles without errors

inline // with and without
int // this can be everything (class, struct, simple type, pointer)
operator|(MyEnum, MyEnum) { return 0; }

#endif

#include <iterator>
--------------------------------------------------------
What line of code does the error message refer to? One of the ones
quoted above? Or one in <iterator>?
 

Re:Cannot convert 'const int *' to 'const ctype_base::mask *'

Thomas Maeder [TeamB] wrote:
Quote
What line of code does the error message refer to? One of the ones
quoted above? Or one in <iterator>?
Error E2034 C:\Borland\CBuilderX\include\stl/_ctype.h 124: Cannot convert
'const int *' to 'const ctype_base::mask *' in function
ctype<char>::classic_table()
And that is not the only error message related to this compiler bug.
I have another file where after including "qnamespace.h" (see first
posting, contains this operator) the compiler can no more call a function
like this:
void Func(const MyEnum* );
MyEnum c = bla;
Func(&c); // here it fails with something like this: "cannot convert
MyEnum* to MyEnum*"
This is very strange. And the alternativ bccx (that does not have this
bug) has no usable standard c/c++ library. There are more functions left
out than included in this dinkumware unabridged library.
--
Regards,
Andreas Hausladen
 

Re:Cannot convert 'const int *' to 'const ctype_base::mask *'

Andreas,
I hit a similar bug (wouldn't do a cast with a function argument and it involved an
ampersand) while porting some MSVC code to BCB.
I had to declare a pointer on a separate line and assign to that pointer. Then I
passed the pointer to the function.
You might try:
const ctype_base::mask *MyPtr = (const ctype_base::mask *)&c;
Then pass MyPtr to the function call.
Andreas Hausladen wrote:
Quote
Thomas Maeder [TeamB] wrote:


>What line of code does the error message refer to? One of the ones
>quoted above? Or one in <iterator>?


Error E2034 C:\Borland\CBuilderX\include\stl/_ctype.h 124: Cannot convert
'const int *' to 'const ctype_base::mask *' in function
ctype<char>::classic_table()

And that is not the only error message related to this compiler bug.
I have another file where after including "qnamespace.h" (see first
posting, contains this operator) the compiler can no more call a function
like this:

void Func(const MyEnum* );

MyEnum c = bla;
Func(&c); // here it fails with something like this: "cannot convert
MyEnum* to MyEnum*"


This is very strange. And the alternativ bccx (that does not have this
bug) has no usable standard c/c++ library. There are more functions left
out than included in this dinkumware unabridged library.


 

Re:Cannot convert 'const int *' to 'const ctype_base::mask *'

Randall Parker wrote:
Quote
const ctype_base::mask *MyPtr = (const ctype_base::mask *)&c;

Then pass MyPtr to the function call.
I don't think that I should modify "stl/_ctype.h" where the error happens.
--
Regards,
Andreas Hausladen
 

Re:Cannot convert 'const int *' to 'const ctype_base::mask *'

"Andreas Hausladen" < XXXX@XXXXX.COM >writes:
Quote
Thomas Maeder [TeamB] wrote:

>What line of code does the error message refer to? One of the ones
>quoted above? Or one in <iterator>?

Error E2034 C:\Borland\CBuilderX\include\stl/_ctype.h 124: Cannot convert
'const int *' to 'const ctype_base::mask *' in function
ctype<char>::classic_table()
The minimal program exposing the bug that I am able to produce using
C++BuilderX is:
enum E
{
};
E operator|(E, E) { return E(); }
enum E2
{
};
E2 m;
E2* mp(&m);
The obvious first step to working around this is to change the return
type of the operator| to E, which seems more natural anyway. The bad
thing is that this doesn't help.
What does make the error go away is overloading unary & as well:
enum E {
};
E const *operator&(E const &e) { return 0; }
E *operator&(E &e) { return 0; }
E operator|(E, E) { return E(); }
enum E2
{
};
E2 *operator&(E2 &e)
{
return 0;
}
E2 m;
E2* mp(&m);
The return type of operator| can be int, too.
[I haven't decided yet if I should be proud of finding this or
embarassed of even considering it. :-)]
Of course, implementing these operator&()s is tricky. It could force
you to use inline assembly; I haven't tried very long. And you
wouldn't want to overload it for mask anyway, I think.
Quote
And that is not the only error message related to this compiler bug.
I have another file where after including "qnamespace.h" (see first
posting, contains this operator) the compiler can no more call a function
like this:

void Func(const MyEnum* );

MyEnum c = bla;
Func(&c); // here it fails with something like this: "cannot convert
MyEnum* to MyEnum*"
This goes away with my suggestion, as well.
On another note, I am not really convinced that overloading operator|
for two values of an enum type is such a good idea.
First, most users expect the built-in operator to be invoked if they
invoke E()|E().
And second, E()|E() is a compile time constant without the overload
operator, but no longer with the overloaded operator.
What purpose does "your" operator| serve?
 

Re:Cannot convert 'const int *' to 'const ctype_base::mask *'

Thomas Maeder [TeamB] wrote:
Quote
The minimal program exposing the bug that I am able to produce using
C++BuilderX is:
Unfortunatelly the bug is still present when you #include <iterator>
Quote
The obvious first step to working around this is to change the return
type of the operator| to E, which seems more natural anyway. The bad
thing is that this doesn't help.
In the real code it looks like this:
template <typename Enum>
class QFlags { typedef Enum enum_type; /*lots of operator overloading*/ };
#define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags) \
inline QFlags<Flags::enum_type>operator|(Flags::enum_type f1,
Flags::enum_type f2) \
{ return QFlags<Flags::enum_type>(f1) | f2; } \
inline QFlags<Flags::enum_type>operator|(Flags::enum_type f1,
QFlags<Flags::enum_type>f2) \
{ return f2 | f1; }
Quote
What does make the error go away is overloading unary & as well:
This only solves your minimal "show the bug" code.
Quote
>MyEnum c = bla;
>Func(&c); // here it fails with something like this: "cannot convert
>MyEnum* to MyEnum*"

This goes away with my suggestion, as well.
This is related to the above bug. because if I disable the operator|
overloads the compiler works as expected (bug gives me lots of other
errors because the operator| isn't overloaded, anymore)
Quote
On another note, I am not really convinced that overloading operator|
for two values of an enum type is such a good idea.
My example was a minimal code and has only the bug in common with the
original code. (I always try to make my code examples for bugs as short as
possible)
Quote
First, most users expect the built-in operator to be invoked if they
invoke E()|E().

And second, E()|E() is a compile time constant without the overload
operator, but no longer with the overloaded operator.

What purpose does "your" operator| serve?
It makes enums type-safe for all compilers (that is what I guess from the
#define Q_NO_TYPESAFE_FLAGS which when defined leads to lots of compile
errors because the
inline QFlags<enum_type>operator|(enum_type, enum_type)
is not overloaded.
--
Regards,
Andreas Hausladen