I recently started on a new project to migrate almost 10 years of Solaris developments on Linux. The oldest code I found dates almost from 1992. It is of course a mess of C, C++ written by tens of people on different stages, various internal libraries and external libraries. A complicated Makefile structure which was supposed at some time to support multiple architectures in a rather complicated way. For now the code compiles mostly on solaris 2.6 and 2.8 using CC (most recent version found in the compile env is CC: Sun WorkShop 6 update 2 C++ 5.3 Patch 111685-23 2005/10/14). There have been a previous attempt 2 years ago which failed half way.

So I started this list as an enumeration of the most strange errors I encounter as I advance and they have no straight answer. Maybe it will help someone in a similar case.

Various C/C++ mixing

If the code is a mix of C and C++ you will surely run into trouble. The best guide for this I found at: http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html#faq-32.4x

Errno strange error

/usr/bin/ld: errno: TLS definition in /lib/libc.so.6 section .tbss mismatches non-TLS reference in /.../lib....a(M....o)<br></br>/lib/libc.so.6: could not read symbols: Bad value

This is a strange error which puzzled me. In fact it is related to the way errno.h is handled. If your C code contains

extern int errno;

then the best way is to replace it with

#include <errno.h>

Another solution which is uglier but does not require code change is to include this header using a compiler option

gcc ... -include /usr/include/errno.h ...

Reference info found at: http://www.opencascade.org/org/forum/thread_9224/

Socket library changes

There are a lot of errors I received related to the usage of parameters for accept, bind, setsockopt and other network functions. Usually this require just a type conversion but remember to add #define code to ensure your will not break compatibility with old platform. For example:

M...cc:83: error: invalid conversion from ‘int*’ to ‘socklen_t*’
#ifdef __LINUX__<br></br>  if ( (ns = ::accept(__Channel,(struct sockaddr*)&__Sockaddr,(socklen_t*)&fm)) == -1 )<br></br>#else<br></br>  if ( (ns = ::accept(__Channel,(struct sockaddr*)&__Sockaddr,&fm)) == -1 )<br></br>#endif

*stream header missing

There has been a lot of change in the stream standards and most of the old code will probably work only after including the proper headers. Here is an example of error:

../include/M....h:9:23: error: strstream.h: No such file or directory<br></br>../include/M....h:183: error: ‘ostrstream’ has not been declared<br></br>../include/M....h:221: error: ‘ostrstream’ has not been declared<br></br>../include/M....h:221: error: ‘ostrstream’ has not been declared<br></br>../include/M....h:261: error: ‘ostrstream’ has not been declared<br></br>../include/M....h:319: error: ‘ostrstream’ has not been declared<br></br>../include/M....h:341: error: ‘ostrstream’ has not been declared<br></br>

and the solution:

#ifdef __LINUX__<br></br>  #include <strstream><br></br>#else<br></br>  #include <strstream.h> <br></br>#endif<br></br>

This type of solution will solve most of the problems but there is one which will require more changes to the code.

Extra qualification on member

This error only signifies that the function declaration inside of a class should not contain the ClassName:: anymore.

class C{<br></br>public:<br></br>void C::methodA();<br></br>}<br></br>

should be

class C{<br></br>public:<br></br>void methodA();<br></br>}

ios:nocreate does not exist anymore

There is a solution described here: http://gcc.gnu.org/ml/gcc-help/2002-09/msg00220.html

#ifdef __LINUX__<br></br>        fstream h(fileName_.data(), ios::in);<br></br>        if(!h){<br></br>        }else{<br></br>          h.close();<br></br>          h.open(fileName_.data(), ios::out);<br></br>        }<br></br>        //from http://gcc.gnu.org/ml/gcc-help/2002-09/msg00220.html<br></br>#else<br></br>        fstream h(fileName_.data(), ios::in | ios::nocreate);<br></br>#endif<br></br>

Bad fstream open parameters

This is error is much more devious as it does not reveals itself at compile time but if fact at run time when nothing works. Take a look at the following code

fstream h(fileName_.data(), ios::app);

or

fstream h(fileName_.data(), fstream::in|fstream::out|fstream::app);<br></br>

This last one is also can be found on numerous examples on the net for instance here: http://www.cplusplus.com/reference/iostream/fstream/open.html

But in fact if you look at the C++ standard both of these are illegal http://gcc.gnu.org/ml/gcc-prs/2003-04/msg00771.html

What is not illegal is:

fstream h(fileName_.data(), fstream::out|fstream::app);<br></br>

Take a look here at table 11: File open modes: http://ftp.csci.csusb.edu/dick/c++std/cd2/lib-iostreams.html#lib.file.streams

Old yacc generated code

This was a particular tricky problem as the C generated code did not compiled and trying to regenerate the code from the .y source generated more problems again. The old C code generated some strange types of errors:

...Protocol.c:101: error: conflicting types for ‘__M....’<br></br>...Protocol.c:48: error: previous declaration of ‘__M....’ was here<br></br>

In my case the initial idea to search for the __M…. function definitions but in fact this meant the yyparse function was #defined as __M…. and then redefined again. The solution was to add various conditional checks if the yyparse symbol was defined.

#ifndef yyparse<br></br>	int yyparse(void);<br></br>#endif<br></br>

Another problem which took a lot of time to figure out was to solve the large number of errors similar to:

...Protocol.c: In function ‘yyget.....’:<br></br>...Protocol.c:197: error: invalid type argument of ‘unary *’<br></br>...Protocol.c:200: error: invalid type argument of ‘unary *’<br></br>...Protocol.c: In function ‘yyM....’:<br></br>...Protocol.c:211: error: too many arguments to function ‘__MMP...’<br></br>...Protocol.c: In function ‘__MM......’:<br></br>...Protocol.c:615: error: invalid type argument of ‘unary *’<br></br>...Protocol.c:658: error: invalid type argument of ‘unary *’<br></br>...Protocol.c:658: error: invalid type argument of ‘unary *’<br></br>...Protocol.c:854: error: invalid type argument of ‘unary *’<br></br>...Protocol.c:866: error: invalid type argument of ‘unary *’<br></br>

All errors seemed to be related to the presence of yylval and yyval in the code on the lines generating the error. The solution came by accident almost as I compared several generated files. All the files which generated the errors seemed to be missing:

YYSTYPE yylval;<br></br>YYSTYPE yyval;<br></br>

Strangely this compiled back on Solaris. After reading a bit more I understood the cause but still the solution came by accident.

Vtable errors

./linux/XX.o: In function `~XX':<br></br>XX.h:33: undefined reference to `vtable for XX'<br></br>

See: http://gcc.gnu.org/faq.html#vtables