Discussion:
[omniORB] Problem passing an array of structs
W T Meyer
2007-05-08 02:41:16 UTC
Permalink
I'm trying to pass a fixed-length array of structs and I'm getting a
cryptic error message. I see others have posted similar - but not
identical - problems and it is not clear to me what the solution or
workaround is. Can someone provide some insight?

Here is my IDL:
------------
module CoRCC {

enum vmeType {SBC, ROD, TIM, EMPTY, OTHER, UNKNOWNTYPE};
enum vmeModStatus {OK, WARNING, ERROR, UNKNOWNSTATUS};
struct slotInfo {
vmeType contents;
long serNo;
vmeModStatus status;
long revision;
};

typedef slotInfo crateInfo[22];

interface RCC {
long scanCrate(out crateInfo modList);
}; /* end of interface RCC */
}; /* end of module CoRCC */
-----------
In my server application, everything compiles and links with no
warnings or errors.

When I try to build a client, I get the following error message:
-------------
CoRCCClient.cc:92: choosing `T& _CORBA_Array_Fix_Var<T_Helper,
T>::operator[](long unsigned int) [with T_Helper =
CoRCC::crateInfo_copyHelper, T = CoRCC::crateInfo_slice]' over `operator[]'
CoRCCClient.cc:92: because worst conversion for the former is better than
worst conversion for the latter
-------------

The relevant part of the client code is as follows:
-------------
int ScanCrate(int rccHandle) {
int status = 0;
int serNo;
CoRCC::crateInfo_var modList = new CoRCC::crateInfo();
status = rccref[rccHandle]->scanCrate(modList);
for (int i=2; i<NSLOTS+1; i++) {
cout << "Slot Number " << i << endl;
serNo = modList[i].serNo; //<<<< This is line 92,
where the error is
}
return status;
}
Luke Deller
2007-05-08 08:41:39 UTC
Permalink
W T Meyer wrote:
...
Post by W T Meyer
CoRCCClient.cc:92: choosing `T& _CORBA_Array_Fix_Var<T_Helper,
T>::operator[](long unsigned int) [with T_Helper =
CoRCC::crateInfo_copyHelper, T = CoRCC::crateInfo_slice]' over
`operator[]'
CoRCCClient.cc:92: because worst conversion for the former is better
than worst conversion for the latter
...

Are you sure this is an error message? It looks like a warning to me.
The message says that the compiler is making a choice which is correct.

Quick fix: use (*modList)[i] instead of modList[i] to avoid the warning.

To explain: the expression modList[i] is potentially ambiguous.
modList is of type CoRCC::crateInfo_var, which includes the following
two member functions:

(1) operator CoRCC::crateInfo_slice * () const;
(2) CoRCC::crateInfo_slice & operator[] (_CORBA_ULong index_);

So modList can be implicitly converted to a pointer using (1).
The [] operator has been overloaded for this class with (2).

Now modList[i] could mean "implicitly convert modList to a pointer using
(1) and then use the built-in [] operator". That's what the compiler
would do if the [] operator hadn't been explicitly overloaded. But
since the [] operator *has* been explicitly overloaded, it will choose
to use (2) instead. The warning message states that the compiler has
made this choice, which is fine. In fact either works correctly.

If you use (*modList)[i] then you remove the ambiguity by forcing
modList to be converted to a pointer, so the warning should go away.

Regards,
Luke.
**********************************************************************************************
Important Note
This email (including any attachments) contains information which is confidential and may be subject to legal privilege. If you are not the intended recipient you must not use, distribute or copy this email. If you have received this email in error please notify the
sender immediately and delete this email. Any views expressed in this email are not necessarily the views of IRESS Market Technology Limited.

It is the duty of the recipient to virus scan and otherwise test the information provided before loading onto any computer system.
IRESS Market Technology Limited does not warrant that the information is free of a virus or any other defect or error.
**********************************************************************************************
W T Meyer
2007-05-19 03:24:21 UTC
Permalink
Since no one else responded, I'll answer my own question. I know how
to get around the problem, but I don't understand why it is a problem.

Apparently operator[] is overloaded in omniORB only for unsigned
int. When I changed the index variable i in line 90 from "int i" to
"unsigned int i" everything worked. The error message is somewhat
less than transparent in pointing to the problem.

Is there a reason for requiring unsigned ints? If so, is there a way
to give the hapless user a more helpful error message?

Regards,

Tom
Post by W T Meyer
I'm trying to pass a fixed-length array of structs and I'm getting a
cryptic error message. I see others have posted similar - but not
identical - problems and it is not clear to me what the solution or
workaround is. Can someone provide some insight?
------------
module CoRCC {
enum vmeType {SBC, ROD, TIM, EMPTY, OTHER, UNKNOWNTYPE};
enum vmeModStatus {OK, WARNING, ERROR, UNKNOWNSTATUS};
struct slotInfo {
vmeType contents;
long serNo;
vmeModStatus status;
long revision;
};
typedef slotInfo crateInfo[22];
interface RCC {
long scanCrate(out crateInfo modList);
}; /* end of interface RCC */
}; /* end of module CoRCC */
-----------
In my server application, everything compiles and links with no
warnings or errors.
-------------
CoRCCClient.cc:92: choosing `T& _CORBA_Array_Fix_Var<T_Helper,
T>::operator[](long unsigned int) [with T_Helper =
CoRCC::crateInfo_copyHelper, T = CoRCC::crateInfo_slice]' over `operator[]'
CoRCCClient.cc:92: because worst conversion for the former is better than
worst conversion for the latter
-------------
-------------
int ScanCrate(int rccHandle) {
int status = 0;
int serNo;
CoRCC::crateInfo_var modList = new CoRCC::crateInfo();
status = rccref[rccHandle]->scanCrate(modList);
for (int i=2; i<NSLOTS+1; i++) {
cout << "Slot Number " << i << endl;
serNo = modList[i].serNo; //<<<< This is line 92,
where the error is
}
return status;
}
_______________________________________________
omniORB-list mailing list
http://www.omniorb-support.com/mailman/listinfo/omniorb-list
Thomas Lockhart
2007-05-19 05:15:04 UTC
Permalink
Apparently operator[] is overloaded in omniORB only for unsigned int.
When I changed the index variable i in line 90 from "int i" to
"unsigned int i" everything worked. The error message is somewhat
less than transparent in pointing to the problem.
Right.
Is there a reason for requiring unsigned ints? If so, is there a way
to give the hapless user a more helpful error message?
Unsigned int means that you (that is, omniORB marshalling) does not need
to do bounds checking for negative values. If one supported both signed
and unsigned ints with explicit code (for example, having a signed int
signature which does checks and then calls the current method), then the
amount of generated code would increase.

It may be that the C++ mapping standard requires support for unsigned
int and disallows support for signed ints, but I haven't looked to
verify this.

Unfortunately, the error message is coming from the compiler. No chance
to fix that without also changing the code the compiler is reading.

hth

- Tom
Duncan Grisby
2007-05-19 21:39:22 UTC
Permalink
Post by W T Meyer
Since no one else responded, I'll answer my own question. I know how
to get around the problem, but I don't understand why it is a problem.
Apparently operator[] is overloaded in omniORB only for unsigned int.
When I changed the index variable i in line 90 from "int i" to
"unsigned int i" everything worked. The error message is somewhat less
than transparent in pointing to the problem.
Is there a reason for requiring unsigned ints? If so, is there a way
to give the hapless user a more helpful error message?
The C++ mapping specifies that operator[] should be defined just for
CORBA::ULong (see page 1-49 of the C++ 1.1 mapping).

The "error" is actually just a warning, and I don't think there's
anything omniORB can do to make it clearer -- it's the C++ compiler that
chooses its warning messages.

Cheers,

Duncan.
--
-- Duncan Grisby --
-- ***@grisby.org --
-- http://www.grisby.org --
W T Meyer
2007-05-22 01:09:12 UTC
Permalink
Post by Duncan Grisby
Post by W T Meyer
Since no one else responded, I'll answer my own question. I know how
to get around the problem, but I don't understand why it is a problem.
Apparently operator[] is overloaded in omniORB only for unsigned int.
When I changed the index variable i in line 90 from "int i" to
"unsigned int i" everything worked. The error message is somewhat less
than transparent in pointing to the problem.
Is there a reason for requiring unsigned ints? If so, is there a way
to give the hapless user a more helpful error message?
The C++ mapping specifies that operator[] should be defined just for
CORBA::ULong (see page 1-49 of the C++ 1.1 mapping).
Yes, and I now see that all the examples in my CORBA books use
CORBA::ULONG for the index, but none of them says why, or that you
have to. Since many of us are used to using an int or a long for
array indices in C++, it is a natural trap to fall into. Few of us
wade through the official CORBA binding to C++ - as you say in the
omniORB docs, it's a tough read.

Even though the dense error message comes from the g++ compiler, is
there more that can be done to make it easier for us that fall into
this trap to figure it out? It took me several frustrating weeks to
get to the bottom of it. The lack of responses to my post made it
that much harder. How about adding an FAQ, so a Google search on
something like "omniORB worst conversion" turns up the answer?

Thanks for your help,

Tom Meyer
Post by Duncan Grisby
The "error" is actually just a warning, and I don't think there's
anything omniORB can do to make it clearer -- it's the C++ compiler that
chooses its warning messages.
Cheers,
Duncan.
--
-- Duncan Grisby --
-- http://www.grisby.org --
Duncan Grisby
2007-05-22 02:13:18 UTC
Permalink
Post by W T Meyer
Even though the dense error message comes from the g++ compiler, is
there more that can be done to make it easier for us that fall into
this trap to figure it out? It took me several frustrating weeks to
get to the bottom of it. The lack of responses to my post made it that
much harder. How about adding an FAQ, so a Google search on something
like "omniORB worst conversion" turns up the answer?
There is an FAQ, but it doesn't include this question. It's a Wiki, so
why don't you add your question and answer to it?

http://www.omniorb-support.com/omniwiki/FrequentlyAskedQuestions

Cheers,

Duncan.
--
-- Duncan Grisby --
-- ***@grisby.org --
-- http://www.grisby.org --
Brian Neal
2007-05-22 18:46:44 UTC
Permalink
Post by W T Meyer
Post by Duncan Grisby
The C++ mapping specifies that operator[] should be defined just for
CORBA::ULong (see page 1-49 of the C++ 1.1 mapping).
Yes, and I now see that all the examples in my CORBA books use
CORBA::ULONG for the index, but none of them says why, or that you
have to. Since many of us are used to using an int or a long for
array indices in C++, it is a natural trap to fall into. Few of us
wade through the official CORBA binding to C++ - as you say in the
omniORB docs, it's a tough read.
I have been (unfortunately.. :-) ) doing CORBA for a few years now,
and I can sympathize as I have made mistakes like this. However, in my
experience, if you are going to be doing CORBA in C++, you really do
need 2 things: The Henning and Vinoski "Advanced CORBA Programming
with C++" book, and a copy of the latest C++ mapping from the OMG. The
mapping document isn't that hard to read, and in fact, I find it under
specified. I wish they would say more. I do refer to it often though.

(Getting a new, better, more modern C++ mapping probably isn't going
to happen sadly)

Continue reading on narkive:
Loading...