[Boost.Format] 64 bit failure test case

This test code aborts at run time when compiled against version 1.31 of the boost libraries using g++ 3.3.3 on a Linux/Alpha machine (64bit architecture.). It also aborts at run time when compiled against current cvs. #include <boost/format.hpp> #include <string> #include <iostream> using std::string; string bformat(string const & fmt, string const & arg1) { return (boost::format(fmt) % arg1).str(); } int main() { std::cout << bformat("Creating directory %1$s and running configure...", "/home/foo/.bar") << std::endl; return 0; } I believe that I have tracked down the cause of the failure. Adding this patch to format/feed_args.hpp $ diff -u lyx/devel/boost/boost/format/feed_args_orig.hpp lyx/devel/boost/boost/format/feed_args.hpp --- lyx/devel/boost/boost/format/feed_args_orig.hpp 2004-03-24 15:13:50.000000000 +0000 +++ lyx/devel/boost/boost/format/feed_args.hpp 2004-03-24 15:10:59.000000000 +0000 @@ -162,6 +162,14 @@ static_cast<std::streamsize>(specs.truncate_ - !!prefix_space), oss_.pcount()); + std::cout << "std::numeric_limits<std::streamsize>::max() " << std::numeric_limits<std::streamsize>::max() << '\n' + << "specs.truncate_ " << specs.truncate_ << '\n' + << "!!prefix_space " << !!prefix_space << '\n' + << "static_cast<std::streamsize>(a - b) " + << static_cast<std::streamsize>(specs.truncate_ - !!prefix_space) << '\n' + << "oss_.pcount() " << oss_.pcount() << '\n' + << "res_size " << res_size << std::endl; + mk_str(res, res_beg, res_size, w, oss_.fill(), fl, prefix_space, (specs.pad_scheme_ & format_item_t::centered) !=0 ); } leads to the following output prior to the code aborting: $ ./trial std::numeric_limits<std::streamsize>::max() 9223372036854775807 specs.truncate_ -1 !!prefix_space 0 static_cast<std::streamsize>(a - b) -1 oss_.pcount() 14 res_size -1 Aborted specs.truncate_ is being initialised incorrectly in the format_item constructor because it is an int (sizeof(4)) whilst std::streamsize has sizeof(8) on the Alpha. FWIW, I attach the gdb backtrace also. Note the 'size == -1' in #9 of this backtrace. Hoping this all makes sense, Regards, Angus (gdb) where #0 0x00000200002384a8 in kill () from /lib/libc.so.6.1 #1 0x0000020000238224 in raise () from /lib/libc.so.6.1 #2 0x0000020000239bb0 in abort () from /lib/libc.so.6.1 #3 0x00000200000ff638 in __cxa_call_unexpected () from /usr/lib/libstdc++.so.5 #4 0x00000200000ff690 in std::terminate() () from /usr/lib/libstdc++.so.5 #5 0x00000200000ff82c in __cxa_throw () from /usr/lib/libstdc++.so.5 #6 0x0000020000098d30 in std::__throw_length_error(char const*) () from /usr/lib/libstdc++.so.5 #7 0x00000200000ed348 in std::string& std::string::_M_replace_safe<char const*>(__gnu_cxx::__normal_iterator<char*, std::string>, __gnu_cxx::__normal_iterator<char*, std::string>, char const*, char const*) () from /usr/lib/libstdc++.so.5 #8 0x00000200000e9a34 in std::string::append(char const*, unsigned long) () from /usr/lib/libstdc++.so.5 #9 0x0000000120008ec8 in void boost::io::detail::(anonymous namespace)::mk_str<char, std::char_traits<char> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, char const*, long, long, char, std::_Ios_Fmtflags, char, bool) ( res=@0x120025a58, beg=0x1200265e8 "/home/foo/.bar", size=-1, w=0, fill_char=32 ' ', f=4098, prefix_space=0 '\0', center=false) at feed_args.hpp:73 #10 0x0000000120008568 in void boost::io::detail::(anonymous namespace)::put<char, std::char_traits<char>, std::string const&>(std::string const&, boost::io::detail::format_item<char, std::char_traits<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, boost::io::basic_outsstream<char, std::char_traits<char> >&) (x=@0x11ffff950, specs=@0x120025a50, res=@0x120025a58, oss_=@0x11ffff738) at feed_args.hpp:165 #11 0x0000000120007544 in void boost::io::detail::distribute<char, std::char_traits<char>, std::string const&>(boost::basic_format<char, std::char_traits<char>
&, std::string const&) (self=@0x11ffff6e0, x=@0x11ffff950) at feed_args.hpp:241 #12 0x00000001200056c8 in boost::basic_format<char, std::char_traits<char> >& boost::io::detail::feed<char, std::char_traits<char>, std::string const&>(boost::basic_format<char, std::char_traits<char> >&, std::string const&) ( self=@0x11ffff6e0, x=@0x11ffff950) at feed_args.hpp:249 #13 0x0000000120003b0c in operator%<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > (this=0x11ffff6e0, x=@0x11ffff950) at format_class.hpp:61 #14 0x00000001200035f8 in bformat(std::string const&, std::string const&) ( fmt=@0x11ffff930, arg1=@0x11ffff950) at trial.C:11 #15 0x0000000120003748 in main () at trial.C:16

Angus Leeming wrote:
specs.truncate_ is being initialised incorrectly in the format_item constructor because it is an int (sizeof(4)) whilst std::streamsize has sizeof(8) on the Alpha.
Sorry, I should have added that changing format_item::truncate_ to std::streamsize truncate_; //- is set for directives like %.5s that ask truncation results in the test code running correctly. I do not know what other implications this has. Regards, Angus

On Wed, 2004-03-24 at 17:25, Angus Leeming wrote:
Angus Leeming wrote:
specs.truncate_ is being initialised incorrectly in the format_item constructor because it is an int (sizeof(4)) whilst std::streamsize has sizeof(8) on the Alpha.
Sorry, I should have added that changing format_item::truncate_ to
std::streamsize truncate_; //- is set for directives like %.5s that ask truncation
results in the test code running correctly. I do not know what other implications this has.
You're absolutely right, I can't find any reason why truncate_ ended up as an int while everything else indicates it's supposed to be streamsize. I probably forgot to change it to streamsize at some point.. I'm curious, was the initialization truncate_(max_streamsize()) producing any warning on your platform ? Anyway, I fixed it in CVS (expect some delay for change to appear in the anonymous CVS). Thanks for reporting this bug, with so much precision ! -- Samuel

Samuel Krempp wrote:
I'm curious, was the initialization truncate_(max_streamsize()) producing any warning on your platform ?
Strangely, no. g++ is usually pretty good at diagnosing this sort of problem. Trying this test program on two different compilers reveals somethig odd though: #include <iostream> int main() { std::streamsize const a(1); int const b(a); std::streamsize c(1); int const d(c); std::cout << "sizeof(a) == " << sizeof(a) << ", sizeof(b) == " << sizeof(b) << ", sizeof(c) == " << sizeof(c) << ", sizeof(d) == " << sizeof(d) << std::endl; return 0; } Compiling it with g++ 3.3 on an Alpha running linux: aleem@thorax:aleem$ g++ -W -Wall -pedantic -o trial trial.C aleem@thorax:aleem$ ./trial sizeof(a) == 8, sizeof(b) == 4, sizeof(c) == 8, sizeof(d) == 4 No warnings :-( Compiling it with DEC/Compaq/HP cxx 6.3 on an Alpha running tru64 unix: aleem@pneumon:aleem-> cxx -std strict_ansi -w0 -o trial trial.C cxx: Info: trial.C, line 8: conversion to integral type of smaller size could lose data int const d(c); --------------------^ cxx: Info: trial.C, line 6: variable "b" was set but never used int const b(a); ------------------^ cxx: Info: trial.C, line 8: variable "d" was set but never used int const d(c); ------------------^ aleem@pneumon:aleem-> ./trial sizeof(a) == 8, sizeof(b) == 4, sizeof(c) == 8, sizeof(d) == 4 A couple of spurious warnings, but at least it also warns about the assignment of the non-const 'c' to an int. All very odd.
Anyway, I fixed it in CVS (expect some delay for change to appear in the anonymous CVS).
Thanks for reporting this bug, with so much precision !
My pleasure. Angus
participants (2)
-
Angus Leeming
-
Samuel Krempp