(const) char[] (i.e. size unknown) cannot be used with O(U)String

msvc can't handle the necessary template overload (and maybe it's
right, I'm not sure)
This commit is contained in:
Luboš Luňák
2012-03-29 11:03:47 +02:00
parent a159dfbea3
commit 8aa60b51a9
4 changed files with 29 additions and 7 deletions

View File

@@ -65,6 +65,12 @@ There are 2 cases:
cast to const char*. Additionally (non-const) char[N] needs to be handled, but with the reference cast to const char*. Additionally (non-const) char[N] needs to be handled, but with the reference
being const, it would also match const char[N], so another overload with a reference to non-const being const, it would also match const char[N], so another overload with a reference to non-const
and NonConstCharArrayDetector are used to ensure the function is called only with (non-const) char[N]. and NonConstCharArrayDetector are used to ensure the function is called only with (non-const) char[N].
Additionally, char[] and const char[] (i.e. size unknown) are rather tricky. Their usage with 'T&' would
mean it would be 'char(&)[]', which seems to be invalid. But gcc and clang somehow manage when it is
a template. while msvc complains about no conversion from char[] to char[1]. And the reference cannot
be avoided, because 'const char[]' as argument type would match also 'const char[N]'
So char[] and const char[] should always be used with their contents specified (which automatically
turns them into char[N] or const char[N]), or char* and const char* should be used.
*/ */
struct Dummy {}; struct Dummy {};
template< typename T1, typename T2 > template< typename T1, typename T2 >
@@ -91,6 +97,8 @@ struct NonConstCharArrayDetector< char[ N ], T >
{ {
typedef T Type; typedef T Type;
}; };
#ifdef RTL_STRING_UNITTEST
// never use, until all compilers handle this
template< typename T > template< typename T >
struct NonConstCharArrayDetector< char[], T > struct NonConstCharArrayDetector< char[], T >
{ {
@@ -101,6 +109,7 @@ struct NonConstCharArrayDetector< const char[], T >
{ {
typedef T Type; typedef T Type;
}; };
#endif
template< typename T1, typename T2 > template< typename T1, typename T2 >
struct ConstCharArrayDetector struct ConstCharArrayDetector

View File

@@ -66,6 +66,9 @@ private:
void testcall( const char str[] ); void testcall( const char str[] );
static const char bad5[];
static char bad6[];
CPPUNIT_TEST_SUITE(StringLiterals); CPPUNIT_TEST_SUITE(StringLiterals);
CPPUNIT_TEST(checkCtors); CPPUNIT_TEST(checkCtors);
CPPUNIT_TEST(checkUsage); CPPUNIT_TEST(checkUsage);
@@ -100,13 +103,20 @@ void test::ostring::StringLiterals::checkCtors()
const char* bad4[] = { "test1" }; const char* bad4[] = { "test1" };
CPPUNIT_ASSERT( !CONST_CTOR_USED( bad4[ 0 ] )); CPPUNIT_ASSERT( !CONST_CTOR_USED( bad4[ 0 ] ));
testcall( good1 ); testcall( good1 );
#ifndef _MSC_VER
// this is actually not supposed to work (see discussion in stringutils.hxx),
// but gcc and clang somehow manage, so keep it used, just in case some other problem
// shows up somewhen in the future
CPPUNIT_ASSERT( !CONST_CTOR_USED( bad5 )); // size is not known here
CPPUNIT_ASSERT( !CONST_CTOR_USED( bad6 ));
#endif
// This one is technically broken, since the first element is 6 characters test\0\0, // This one is technically broken, since the first element is 6 characters test\0\0,
// but there does not appear a way to detect this by compile time (runtime will complain). // but there does not appear a way to detect this by compile time (runtime will complain).
// RTL_CONSTASCII_USTRINGPARAM() has the same flaw. // RTL_CONSTASCII_USTRINGPARAM() has the same flaw.
const char bad5[][ 6 ] = { "test", "test2" }; const char bad7[][ 6 ] = { "test", "test2" };
CPPUNIT_ASSERT( CONST_CTOR_USED( bad5[ 0 ] )); CPPUNIT_ASSERT( CONST_CTOR_USED( bad7[ 0 ] ));
CPPUNIT_ASSERT( CONST_CTOR_USED( bad5[ 1 ] )); CPPUNIT_ASSERT( CONST_CTOR_USED( bad7[ 1 ] ));
// Check that contents are correct and equal to the case when const char* ctor is used. // Check that contents are correct and equal to the case when const char* ctor is used.
CPPUNIT_ASSERT( rtl::OString( (const char*)"" ) == rtl::OString( "" )); CPPUNIT_ASSERT( rtl::OString( (const char*)"" ) == rtl::OString( "" ));
@@ -128,6 +138,9 @@ void test::ostring::StringLiterals::checkCtors()
#endif #endif
} }
const char test::ostring::StringLiterals::bad5[] = "test";
char test::ostring::StringLiterals::bad6[] = "test";
void test::ostring::StringLiterals::testcall( const char str[] ) void test::ostring::StringLiterals::testcall( const char str[] )
{ {
#ifndef _MSC_VER #ifndef _MSC_VER

View File

@@ -79,10 +79,10 @@ using rtl::OUStringBuffer;
using sw::mark::IMark; using sw::mark::IMark;
#if defined(UNX) #if defined(UNX22)
const sal_Char RtfExport::sNewLine = '\012'; const sal_Char RtfExport::sNewLine = '\012';
#else #else
const sal_Char RtfExport::sNewLine[] = "\015\012"; const sal_Char* const RtfExport::sNewLine = "\015\012";
#endif #endif
// the default text encoding for the export, if it doesn't fit unicode will // the default text encoding for the export, if it doesn't fit unicode will

View File

@@ -155,10 +155,10 @@ public:
/// Destructor. /// Destructor.
virtual ~RtfExport(); virtual ~RtfExport();
#if defined(UNX) #if defined(UNX22)
static const sal_Char sNewLine; // \012 or \015 static const sal_Char sNewLine; // \012 or \015
#else #else
static const sal_Char sNewLine[]; // \015\012 static const sal_Char* const sNewLine; // \015\012
#endif #endif
rtl_TextEncoding eDefaultEncoding; rtl_TextEncoding eDefaultEncoding;