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