Discussion:
[omniORB] Declaration of _CORBA_ULONGLONG_DECL on gcc (32 and 64 - bit)
Matej Kenda
2009-06-08 13:57:00 UTC
Permalink
Hi,

I have noticed an inconsistency between the declarations of 64-bit
integers in CORBA_sysdep_trad.h and CORBA_sysdep_auto.h when compiling
with gcc.

* _trad:

// GCC claims to support long long on all platforms
# define HAS_LongLong
# define HAS_LongDouble
# define _CORBA_LONGLONG_DECL long long
# define _CORBA_ULONGLONG_DECL unsigned long long
# define _CORBA_LONGDOUBLE_DECL long double
# define _CORBA_LONGLONG_CONST(x) (x##LL)

* _auto:

#if defined(SIZEOF_LONG) && (SIZEOF_LONG == 8)
# define HAS_LongLong
# define _CORBA_LONGLONG_DECL long
# define _CORBA_ULONGLONG_DECL unsigned long
# define _CORBA_LONGLONG_CONST(x) (x)

#elif defined(SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 8)
# define HAS_LongLong
# define _CORBA_LONGLONG_DECL long long
# define _CORBA_ULONGLONG_DECL unsigned long long
# define _CORBA_LONGLONG_CONST(x) (x##LL)
#endif

When compiling with gcc for 32-bit target, CORBA::UlongLong is defined
as "unsigned long long" in both cases, however when compiling for
64-bit target, CORBA::UlongLong is defined as "unsigned long long" or
"unsigned long" respectively.

The consequence of this inconsistency is that source code that
compiles well for 32-bit target, doesn't compile for 64-bit target,
when using _auto.h.

Example:

CORBA::Any_var any_value;
any_value = server->GetParameterByName("parameter.name");
unsigned long long value;
any_value ==> value;

This code fails to compile for 64-bit target:

src/Application.cpp:380: error: no match for ?operator>>=? in
?any_value >>= value?
/usr/include/omniORB4/CORBA_Any_vartypes.h:200: note: candidates are:
CORBA::Boolean CORBA::Any_var::operator>>=(CORBA::Short&) const
/usr/include/omniORB4/CORBA_Any_vartypes.h:203: note:
CORBA::Boolean CORBA::Any_var::operator>>=(CORBA::UShort&) const
/usr/include/omniORB4/CORBA_Any_vartypes.h:206: note:
CORBA::Boolean CORBA::Any_var::operator>>=(CORBA::Long&) const
/usr/include/omniORB4/CORBA_Any_vartypes.h:209: note:
CORBA::Boolean CORBA::Any_var::operator>>=(CORBA::ULong&) const
/usr/include/omniORB4/CORBA_Any_vartypes.h:213: note:
CORBA::Boolean CORBA::Any_var::operator>>=(CORBA::LongLong&) const
/usr/include/omniORB4/CORBA_Any_vartypes.h:216: note:
CORBA::Boolean CORBA::Any_var::operator>>=(CORBA::ULongLong&) const
/usr/include/omniORB4/CORBA_Any_vartypes.h:221: note:
CORBA::Boolean CORBA::Any_var::operator>>=(CORBA::Float&) const
/usr/include/omniORB4/CORBA_Any_vartypes.h:224: note:
CORBA::Boolean CORBA::Any_var::operator>>=(CORBA::Double&) const
/usr/include/omniORB4/CORBA_Any_vartypes.h:228: note:
CORBA::Boolean CORBA::Any_var::operator>>=(CORBA::LongDouble&) const
/usr/include/omniORB4/CORBA_Any_vartypes.h:233: note:
CORBA::Boolean CORBA::Any_var::operator>>=(const CORBA::Any*&) const
/usr/include/omniORB4/CORBA_Any_vartypes.h:236: note:
CORBA::Boolean CORBA::Any_var::operator>>=(CORBA::Any*&) const
/usr/include/omniORB4/CORBA_Any_vartypes.h:239: note:
CORBA::Boolean CORBA::Any_var::operator>>=(CORBA::Any&) const
/usr/include/omniORB4/CORBA_Any_vartypes.h:242: note:
CORBA::Boolean CORBA::Any_var::operator>>=(CORBA::TypeCode*&) const
/usr/include/omniORB4/CORBA_Any_vartypes.h:245: note:
CORBA::Boolean CORBA::Any_var::operator>>=(const char*&) const
/usr/include/omniORB4/CORBA_Any_vartypes.h:248: note:
CORBA::Boolean CORBA::Any_var::operator>>=(CORBA::Object*&) const
/usr/include/omniORB4/CORBA_Any_vartypes.h:251: note:
CORBA::Boolean CORBA::Any_var::operator>>=(const CORBA::WChar*&) const
/usr/include/omniORB4/CORBA_Any_vartypes.h:254: note:
CORBA::Boolean CORBA::Any_var::operator>>=(CORBA::Any::to_boolean)
const
/usr/include/omniORB4/CORBA_Any_vartypes.h:257: note:
CORBA::Boolean CORBA::Any_var::operator>>=(CORBA::Any::to_char) const
/usr/include/omniORB4/CORBA_Any_vartypes.h:260: note:
CORBA::Boolean CORBA::Any_var::operator>>=(CORBA::Any::to_wchar) const
/usr/include/omniORB4/CORBA_Any_vartypes.h:263: note:
CORBA::Boolean CORBA::Any_var::operator>>=(CORBA::Any::to_octet) const
/usr/include/omniORB4/CORBA_Any_vartypes.h:266: note:
CORBA::Boolean CORBA::Any_var::operator>>=(CORBA::Any::to_string)
const
/usr/include/omniORB4/CORBA_Any_vartypes.h:269: note:
CORBA::Boolean CORBA::Any_var::operator>>=(CORBA::Any::to_wstring)
const
/usr/include/omniORB4/CORBA_Any_vartypes.h:272: note:
CORBA::Boolean CORBA::Any_var::operator>>=(CORBA::Any::to_fixed) const
/usr/include/omniORB4/CORBA_Any_vartypes.h:275: note:
CORBA::Boolean CORBA::Any_var::operator>>=(CORBA::Any::to_object)
const
/usr/include/omniORB4/CORBA_Any_vartypes.h:278: note:
CORBA::Boolean CORBA::Any_var::operator>>=(CORBA::Any::to_abstract_base)
const
/usr/include/omniORB4/CORBA_Any_vartypes.h:281: note:
CORBA::Boolean CORBA::Any_var::operator>>=(CORBA::Any::to_value) const
/usr/include/omniORB4/CORBA_Any_vartypes.h:284: note:
CORBA::Boolean CORBA::Any_var::operator>>=(const
CORBA::SystemException*&) const

I suggest to switch the pre-processor if blocks in _auto.h:

#if defined(SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 8)
# define HAS_LongLong
# define _CORBA_LONGLONG_DECL long long
# define _CORBA_ULONGLONG_DECL unsigned long long
# define _CORBA_LONGLONG_CONST(x) (x##LL)

#elif defined(SIZEOF_LONG) && (SIZEOF_LONG == 8)
# define HAS_LongLong
# define _CORBA_LONGLONG_DECL long
# define _CORBA_ULONGLONG_DECL unsigned long
# define _CORBA_LONGLONG_CONST(x) (x)
#endif

CORBA::ULongLong and CORBA::LongLong would be always defined as
"(unsigned) long long".

I am not aware of implications of this change on non-gcc compilers, however.

Best regards,

Matej
Duncan Grisby
2009-07-02 14:28:05 UTC
Permalink
Post by Matej Kenda
I have noticed an inconsistency between the declarations of 64-bit
integers in CORBA_sysdep_trad.h and CORBA_sysdep_auto.h when compiling
with gcc.
[...]
Post by Matej Kenda
When compiling with gcc for 32-bit target, CORBA::UlongLong is defined
as "unsigned long long" in both cases, however when compiling for
64-bit target, CORBA::UlongLong is defined as "unsigned long long" or
"unsigned long" respectively.
That's a historical artifact -- the trad version predates GCC on 64 bit
platforms. I don't think anyone really uses the trad build on
non-Windows platforms any more do they?
Post by Matej Kenda
The consequence of this inconsistency is that source code that
compiles well for 32-bit target, doesn't compile for 64-bit target,
when using _auto.h.
CORBA::Any_var any_value;
any_value = server->GetParameterByName("parameter.name");
unsigned long long value;
any_value ==> value;
You're not meant to mix non-CORBA types with CORBA types without being
explicit about it, so that's not expected to work in the C++ mapping.
There are too many integer types for all of them to map to CORBA types.
The same issue arises on 32 bit platforms about whether CORBA::Long is
int or long, for example.

I don't think it's appropriate to change the autoconf build to use long
long for 64 bit types on 64 bit platforms. It definitely can't be done
on the 4.1.x branch because it would break binary compatibility.

Of course, nothing stops you from using your own patched version that
does use long long.

Cheers,

Duncan.
--
-- Duncan Grisby --
-- ***@grisby.org --
-- http://www.grisby.org --
Matej Kenda
2009-07-13 16:53:41 UTC
Permalink
Post by Duncan Grisby
That's a historical artifact -- the trad version predates GCC on 64 bit
platforms. I don't think anyone really uses the trad build on
non-Windows platforms any more do they?
I doubt that.
Post by Duncan Grisby
Post by Matej Kenda
CORBA::Any_var any_value;
any_value = server->GetParameterByName("parameter.name");
unsigned long long value;
any_value ==> value;
You're not meant to mix non-CORBA types with CORBA types without being
explicit about it, so that's not expected to work in the C++ mapping.
There are too many integer types for all of them to map to CORBA types.
The same issue arises on 32 bit platforms about whether CORBA::Long is
int or long, for example.
Thank you for the explanation. It is definitely the best thing to do.
Post by Duncan Grisby
I don't think it's appropriate to change the autoconf build to use long
long for 64 bit types on 64 bit platforms. It definitely can't be done
on the 4.1.x branch because it would break binary compatibility.
I can understand that.

Just a suggestion: Would it make sense to use mapping to types,
declared in <inttypes.h>, namely int32_t, uint32_t, int64_t uint64_t?
Post by Duncan Grisby
Of course, nothing stops you from using your own patched version that
does use long long.
Yes, that's true, however I prefer using "standard" packages, provided
by the Linux distribution.

Regards,

Matej

Loading...