logging-log4cxx-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Curt Arnold <carn...@apache.org>
Subject Re: Major problem with wide vs. normal strings in log messages
Date Fri, 23 May 2008 02:37:44 GMT

On May 22, 2008, at 6:21 PM, Dale King wrote:

> I'm going to file a bug on what I consider a major problem with wide
> versus normal character strings and the << operator to append to the
> MessageBuffer. The problem is that the first thing in your message
> determines the behavior of the rest of the message.

That is by design.


> If the first thing
> you output is not a wide string, then any other character strings that
> are wide will be treated as just the pointer value.

That is a side effect of the compiler casting the wchar_t* to int for  
us.  If the L"2"

>
>
> Consider these statements on a platform (i.e. Windows) where WCHAR is
> used with various combinations of wide and normal strings:
>
>    LOG4CXX_TRACE( logger, L"1" << L"2" );
>    LOG4CXX_TRACE( logger, "1" << L"2" );
>    LOG4CXX_TRACE( logger, L"1" << "2" );
>    LOG4CXX_TRACE( logger, 1 << "2" );
>    LOG4CXX_TRACE( logger, 1 << L"2" );
>
> The expected result is 5 logging events all with the message "12".
> Instead I get:
>
>   12
>   1006E1C4C
>   12
>   12
>   1006E1C4C
>
> Most of the << operators in the MessageBuffer class return either
> CharMessageBuffer & or std::ostream &. I think all of these should
> probably be returning MessageBuffer which would allow it to switch to
> a WideMessageBuffer if I ever add a wide string, not just if the first
> string is wide.


The idea of the whole MessageBuffer family was support for  
std::basic_string<char> insertion behavior that the log4cxx 0.9.7  
offered while eliminating the surprisingly expensive (at least for  
some STL implementations) std::basic_ostream<char> constructor when  
you were just logging a single char* and working right when logging  
wchar_t strings.  The last had more flexibility since there wasn't a  
released code base with which we had to be compatible.  Getting that  
to work and working across multiple compilers was to say the least a  
challenge.

As far as I can tell, the behavior you are observing is the same as  
you would get with log4cxx 0.9.7, even if it was not what you would  
expect.

If instead of

>    LOG4CXX_TRACE( logger, "1" << L"2" );

you had done

>    LOG4CXX_TRACE( logger, "1" << std::wstring(L"2") );

you would have gotten a compile error (at least with gcc on Mac OS/ 
X).  That is because the compiler won't quietly cast a std::wstring to  
an int like it does a wchar_t*.  If the first works, then the second  
should also be supported.

Things would really start getting hugely complicated if you started  
inserting objects where one might only have a std::basic_ostream<char>  
insertion operator and another might only have a  
std::basic_ostream<wchar_t> operator.  Then throw in manipulators and  
things just spiral out of control trying to do it perfect.

I'd be leaning toward adding private insertion operations to result in  
a compiler error when you mismatch string types on a logging call.   
That might result in some code that compiled in log4cxx 0.9.7 to fail  
to compile (code that expected the pointer value to be output), but  
that seems like an improvement to break that code.


Mime
View raw message