boycy
asked on
Link problems - undefined reference with ternary operator
I am receiving the following error during linking of my program (with g++ 2.96, RedHat 8, kernel 2.4):
/tmp/ccAC0qDg.o(.text+0x12 9a): In function `StartHardwareThread(void *)':
: undefined reference to `Serial::Baud9600'
/tmp/ccAC0qDg.o(.text+0x12 a5): In function `StartHardwareThread(void *)':
: undefined reference to `Serial::Baud38400'
The line of code that this relates to is the following:
Serial::BaudRate baud = (m_config.find("FastPSoC") == m_config.end()? Serial::Baud9600 : Serial::Baud38400);
The strange thing is, the following line does *not* cause the problem:
Serial::BaudRate baud = (true? Serial::Baud9600 : Serial::Baud38400);
But this does cause the problem:
bool thisIsTrue(true);
Serial::BaudRate baud = (thisIsTrue? Serial::Baud9600 : Serial::Baud38400);
The problem does not occur if I use if...else to control the assignment to variable baud
It seems as if the conditional usage prevents it from linking in properly.
The Serial class is defined in a header file, object code is in a dynamic library (.so for *nix users, .dll for windows users)
Can anyone tell me why this happens?
/tmp/ccAC0qDg.o(.text+0x12
: undefined reference to `Serial::Baud9600'
/tmp/ccAC0qDg.o(.text+0x12
: undefined reference to `Serial::Baud38400'
The line of code that this relates to is the following:
Serial::BaudRate baud = (m_config.find("FastPSoC")
The strange thing is, the following line does *not* cause the problem:
Serial::BaudRate baud = (true? Serial::Baud9600 : Serial::Baud38400);
But this does cause the problem:
bool thisIsTrue(true);
Serial::BaudRate baud = (thisIsTrue? Serial::Baud9600 : Serial::Baud38400);
The problem does not occur if I use if...else to control the assignment to variable baud
It seems as if the conditional usage prevents it from linking in properly.
The Serial class is defined in a header file, object code is in a dynamic library (.so for *nix users, .dll for windows users)
Can anyone tell me why this happens?
Execuse me I mean:
Serial::BaudRate baud = NULL; // or whatever correct
then add the following line:
baud = (m_config.find("FastPSoC") == m_config.end()? Serial::Baud9600 : Serial::Baud38400);
Serial::BaudRate baud = NULL; // or whatever correct
then add the following line:
baud = (m_config.find("FastPSoC")
I have a couple of wild guesses. Maybe one will work for you.
Serial::BaudRate baud = (m_config.find("FastPSoC") == m_config.end()? (Serial::Baud9600) : (Serial::Baud38400));
Serial::BaudRate baud = (m_config.find("FastPSoC") == m_config.end()? (::Serial::Baud9600) : (::Serial::Baud38400));
Serial::BaudRate baud = (m_config.find("FastPSoC")
Serial::BaudRate baud = (m_config.find("FastPSoC")
ASKER
Thanks both for replies - unfortunately neither of them worked :'(
I don't understand what's happening here. Obviously Baud9600 and Baud38400 are defined in the library I'm linking to, their identifiers must be included in the preprocessing/compilation stages otherwise it wouldn't even get to linking. So logically, for some reason the identifiers the linker is looking for are not the same as the identifiers stored in the library....depending on how I use them.
Ok bit more to go on:
Serial::BaudRate baudLow = Serial::Baud9600;
Serial::BaudRate baudHigh = Serial::Baud38400;
Serial::BaudRate baud = (g_config.find("FastPSoC") == g_config.end()? baudLow : baudHigh);
that works fine, as does swapping *one* of baudLow / baudHigh in the last line for Baud9600 / Baud38400 respectively. Swapping both of them does not work. Surely this must be some sort of bug in the linker?
I don't understand what's happening here. Obviously Baud9600 and Baud38400 are defined in the library I'm linking to, their identifiers must be included in the preprocessing/compilation stages otherwise it wouldn't even get to linking. So logically, for some reason the identifiers the linker is looking for are not the same as the identifiers stored in the library....depending on how I use them.
Ok bit more to go on:
Serial::BaudRate baudLow = Serial::Baud9600;
Serial::BaudRate baudHigh = Serial::Baud38400;
Serial::BaudRate baud = (g_config.find("FastPSoC")
that works fine, as does swapping *one* of baudLow / baudHigh in the last line for Baud9600 / Baud38400 respectively. Swapping both of them does not work. Surely this must be some sort of bug in the linker?
What are the exact types of Serial::Baud9600 and 38400? How is Serial::BaudRate defined?
class Serial
{
public:
typedef unsigned int BaudRate;
static const BaudRate Baud9600 B9600;
// ...
}
{
public:
typedef unsigned int BaudRate;
static const BaudRate Baud9600 B9600;
// ...
}
ASKER
Oops, sorry that post was mine -- shared computer :-?
Try compiling your .cc to a .o file (instead of directly to an executable) and run "nm -C" on the resulting .o.
I'm thinking you really have a compiler bug here. Is there a reason you're using g++ 2.96? Maybe a newer version will not have this problem.
I'm thinking you really have a compiler bug here. Is there a reason you're using g++ 2.96? Maybe a newer version will not have this problem.
ASKER
@Nova: which .cc - the one attempting to use the BaudRate constants?
Unfortunately yes there is a reason - the target is embedded Linux and compiling with anything other than those in gcc 2.96 results in link errors on target (as I recall , it attempts to dynamically link to non-existant GLIBC stuff).
Unfortunately yes there is a reason - the target is embedded Linux and compiling with anything other than those in gcc 2.96 results in link errors on target (as I recall , it attempts to dynamically link to non-existant GLIBC stuff).
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
as2003 is not my account, I happen to know the guy and used his computer to post a comment, forgetting to log him out and myself in.
Hello,
Boycy just pointed out your comments GranMod. I can assure you we are two separate entities.
Don't closing either of our accounts. I've put a lot of effort into answering PHP questions. I'll be furious if my progress towards becoming an PHP Expert is erased.
We are good friends and once lived together. He once posted from my computer without logging me out first.
Check out the geographical location of our IPs. You'll notice it's impossible for boycy to travel 200 miles in 1 hour.
Check out our histories. We are interested in totally different topics, our writing style is different, our locations are different. etc. etc.
Boycy just pointed out your comments GranMod. I can assure you we are two separate entities.
Don't closing either of our accounts. I've put a lot of effort into answering PHP questions. I'll be furious if my progress towards becoming an PHP Expert is erased.
We are good friends and once lived together. He once posted from my computer without logging me out first.
Check out the geographical location of our IPs. You'll notice it's impossible for boycy to travel 200 miles in 1 hour.
Check out our histories. We are interested in totally different topics, our writing style is different, our locations are different. etc. etc.
ASKER
I could be using a proxy? Yeah, didn't think of that did you! Anyway I'm not.
Arrr, you got me! I *am* Boycy! hahaha!!! And I hereby confess that I smell of mouldy cheese and like to sniff ladies' shoes.
ASKER
Umm...yeah ok I thnik we've established who's who now....further to earlier points I'd like to dissassociate myself from him to prevent any further embarassment...
While I'm here, NovaDenizen - thanks for your assistance on the issue. Whilst it remains unsolved, you can take the points. I will have to assume it is a compiler bug.
Cheers,
--Rob
While I'm here, NovaDenizen - thanks for your assistance on the issue. Whilst it remains unsolved, you can take the points. I will have to assume it is a compiler bug.
Cheers,
--Rob
like this
Serial::BaudRate baud = NULL; // or whatever correct
then add the following line:
baud = (true? Serial::Baud9600 : Serial::Baud38400);