Link to home
Start Free TrialLog in
Avatar of boycy
boycyFlag for United Kingdom of Great Britain and Northern Ireland

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+0x129a): In function `StartHardwareThread(void *)':
: undefined reference to `Serial::Baud9600'
/tmp/ccAC0qDg.o(.text+0x12a5): 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?
Avatar of bachra04
bachra04
Flag of Canada image

I think you must define baud variables first and then conditional usage.

like this

   Serial::BaudRate baud = NULL; // or whatever correct
   
   then add the following line:
   
   baud = (true? Serial::Baud9600 : Serial::Baud38400);
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);
Avatar of NovaDenizen
NovaDenizen

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));
Avatar of boycy

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?
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;
   // ...
}
Avatar of boycy

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.  
Avatar of boycy

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).
ASKER CERTIFIED SOLUTION
Avatar of NovaDenizen
NovaDenizen

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of boycy

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.
Avatar of boycy

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.
Avatar of boycy

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