Re: problem testing infinint value

Denis Corbin <[email protected]>
Newsgroups gmane.comp.sysutils.backup.dar.general
Organization none
Message-ID <[email protected]>
Johnathan Burchill wrote:
> Hi Denis,

hello Johnathan,

> 
> This code has worked up until now.
> 
> 		QString plural("s ");
> 		libdar::statistics st=op_test(theArchive, selection, subtree, verbose);
> 		if (st.errored == libdar::infinint(1)) plural = " ";
> 
> It compiles fine (dar-2.1.3), but I get the following linker error:
> 
>[...]
 >
> *testArchiveThread.o(.text+0x2dd): In function `testArchiveThread::run()': 
> *: undefined reference to `void libdar::limitint<unsigned long 
> long>::limitint_from<long>(long)' 
> *collect2: ld returned 1 exit status 
> *Making all in doc 
> *gmake[2]: *** [kdar] Error 1 
> *gmake[2]: Target `all' not remade because of errors. 
> *
> 
> The only change was to put the code into a separate .cpp file, which 
> compiles okay. When the code was inside my kdar.cpp file, there was no 
> problem during linkage.

Have you checked the files included in kdar.cpp against those included 
in your separated file ? Has the compiler been changed ?

> 
> The problem line is
> 		if (st.errored == libdar::infinint(1)) plural = " ";
> which can be verified by commenting it out.

for what it seems, the constant '1' in the expression, is cast as "long" 
before being given to the limitint constructor. This is wrong because 
there limitint is *unsigned* and cannot be built from *signed* integers.

Now why compilation succeeds and linkage fails ? Because limitint is a 
template class, the template class should be transparently instanciated 
to a real class when some code makes reference to it. But the "#pragma 
interface" and "#pragma implementation" make the things different. The 
template instanciation must be done explicitely in the body of the 
concerned module (here "libdar/limitint.cpp"). It thus succeeds at 
compilation time because the code is correct, but fails at linking 
because there is no explicit template instanciation of the constructor 
with a "long" (There is two levels of template, the class and the 
constructors, and thus there is two levels of explicit template 
instanciation in "limitint.cpp").

Why using "#pragma interface/implementation" directives ? To avoid 
having many different implementations of the same limitint<unsigned long 
long> class (the template class instanciated by unsigned long long). The 
compiler would duplicate the code as much time as there would be c/c++ 
file making reference to limitint.

To fix the problem, I suggest an explicit cast:

	if (st.errored == libdar::infinint((U_I)1) plural = " ";

U_I is a libdar macro, system independent, matching an unsigned integer.
(see "libdar/integers.hpp"), but if you prefer you can safely replace it 
by "unsigned int".


> 
> Have you any experience with this problem?

I am not sure, maybe yes.

> 
> Thanks,
> JB

waiting for your feedback against this suggestion.

Cheers,
Denis.

P.S.: it should be more appropriate to post to lidar-api mailing-list 
rather than to this general discussion mailing-list for such problems. 
Thanks.



-------------------------------------------------------
This SF.Net email sponsored by Black Hat Briefings & Training.
Attend Black Hat Briefings & Training, Las Vegas July 24-29 - 
digital self defense, top technical experts, no vendor pitches, 
unmatched networking opportunities. Visit www.blackhat.com
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.