TEXT macro for ascii and unicode initialization

B

Blue

I've been relying on gcc compiling this but now it doesn't so I'm
hoping to learn the right way.

See the header below.

TCHAR Message[] = TEXT("Press a Key to Change Setting...");

this basicly becomes

wchar_t Message[] = ((wchar_t *)L"Press a Key to Change Setting..."));

And now I get the gcc error: initializer fails to determine size of
`Message'

I have tried casting to wchar_t[] but that gives it's own error.

What's the legal way of doing this? Without templates please? And
typedef types rather than #define'd equivelents.

The whole point of my types library is so I don't assume built in
types. For instance a character could be 'unsigned char' or 'unsigned
wchar_t" if I wanted, maybe even 'unsigned int'.


I have after some pruning
***************************************

#ifdef DEFAULT_ASCII
#ifdef DEFAULT_UNICODE
#undef DEFAULT_UNICODE
#endif
#endif

#define ASCII_TEXT(x) ((XTYPE::ACHAR *)(x))
#define UNICODE_TEXT(x) ((XTYPE::UCHAR *)(L##x))

namespace XTYPE
{
typedef char ACHAR ;
typedef wchar_t UCHAR ;

typedef ACHAR * ASTRING ;
typedef CONST ACHAR * CASTRING ;

typedef UCHAR * USTRING ;
typedef CONST UCHAR * CUSTRING ;

#ifdef DEFAULT_ASCII
typedef ACHAR CHAR ;
#define TEXT(x) ASCII_TEXT(x)
typedef CHAR * STRING ;
typedef CONST STRING CSTRING ;
typedef CHAR TCHAR ;
typedef TCHAR * TSTRING ;
typedef CONST TSTRING CTSTRING ;
#endif

#ifdef DEFAULT_UNICODE
typedef UCHAR CHAR ;

#define TEXT(x) UNICODE_TEXT(x)

typedef CHAR * STRING ;
typedef CONST STRING CSTRING ;
typedef CHAR TCHAR ;
typedef TCHAR * TSTRING ;
typedef CONST TSTRING CTSTRING ;
#endif
} ;
 
J

Jeff Schwab

Blue said:
I've been relying on gcc compiling this but now it doesn't so I'm
hoping to learn the right way.

See the header below.

TCHAR Message[] = TEXT("Press a Key to Change Setting...");

this basicly becomes

wchar_t Message[] = ((wchar_t *)L"Press a Key to Change Setting..."));

Why are you casting?

int main( )
{
wchar_t Message[] = L"Press a Key to Change Setting...";
}
And now I get the gcc error: initializer fails to determine size of
`Message'

I have tried casting to wchar_t[] but that gives it's own error.

What's the legal way of doing this? Without templates please? And
typedef types rather than #define'd equivelents.
 
R

Rolf Magnus

Blue said:
I've been relying on gcc compiling this but now it doesn't so I'm
hoping to learn the right way.

See the header below.

TCHAR Message[] = TEXT("Press a Key to Change Setting...");

this basicly becomes

wchar_t Message[] = ((wchar_t *)L"Press a Key to Change Setting..."));

And now I get the gcc error: initializer fails to determine size of
`Message'

That's right. You're defining an array without specifying the size. This
is only possible if the compiler can determine the size from the
initializer. But the intializer is a pointer. Why do you cast the
literal into a pointer?
I have tried casting to wchar_t[] but that gives it's own error.

You cannot cast into an array, especially not into one without a size.
What's the legal way of doing this?

Leave out the cast.
Without templates please?
Why?

And typedef types rather than #define'd equivelents.

The whole point of my types library is so I don't assume built in
types. For instance a character could be 'unsigned char' or 'unsigned
wchar_t" if I wanted, maybe even 'unsigned int'.

Why unsigned?
I have after some pruning
***************************************

#ifdef DEFAULT_ASCII
#ifdef DEFAULT_UNICODE
#undef DEFAULT_UNICODE
#endif
#endif

#define ASCII_TEXT(x) ((XTYPE::ACHAR *)(x))
#define UNICODE_TEXT(x) ((XTYPE::UCHAR *)(L##x))

namespace XTYPE
{
typedef char ACHAR ;
typedef wchar_t UCHAR ;

typedef ACHAR * ASTRING ;
typedef CONST ACHAR * CASTRING ;

typedef UCHAR * USTRING ;
typedef CONST UCHAR * CUSTRING ;

#ifdef DEFAULT_ASCII
typedef ACHAR CHAR ;
#define TEXT(x) ASCII_TEXT(x)
typedef CHAR * STRING ;
typedef CONST STRING CSTRING ;
typedef CHAR TCHAR ;
typedef TCHAR * TSTRING ;
typedef CONST TSTRING CTSTRING ;
#endif

#ifdef DEFAULT_UNICODE
typedef UCHAR CHAR ;

#define TEXT(x) UNICODE_TEXT(x)

typedef CHAR * STRING ;
typedef CONST STRING CSTRING ;
typedef CHAR TCHAR ;
typedef TCHAR * TSTRING ;
typedef CONST TSTRING CTSTRING ;
#endif
} ;


Why do all your types SHOUT?
 
P

Phlip

Rolf said:
Why do all your types SHOUT?

Maybe because everyone else was doing it.

Some esthetic style guides put all typedefs into a SHOUTING
pseudo-namespace.

Some postfix a _t.
 
B

Blue

Why are you casting?

Take a look at the code. I'm abstracting strings.

I do it so I can construct strings of any datatype.

I have TCHAR String = TEXT("Hello World\n") so the code is written and
I can choose at compile time if I want the application to use ASCII by
default or unicode. I can also decide if I want string literals to be
const by default. Simple abstraction. I use to use defines but then
I decovered how wonderful typedef can be. If this just isn't possible
anymore I'll have to go back to full macro data types.
 
P

Phlip

Blue said:
Take a look at the code. I'm abstracting strings.

I do it so I can construct strings of any datatype.

I have TCHAR String = TEXT("Hello World\n") so the code is written and
I can choose at compile time if I want the application to use ASCII by
default or unicode. I can also decide if I want string literals to be
const by default. Simple abstraction. I use to use defines but then
I decovered how wonderful typedef can be. If this just isn't possible
anymore I'll have to go back to full macro data types.

But why are you casting?

Always try to remove typecasts. The better your design, the less likely they
are needed. Only use them in a pinch.
 
B

Blue

Blue said:
I've been relying on gcc compiling this but now it doesn't so I'm
hoping to learn the right way.

See the header below.

TCHAR Message[] = TEXT("Press a Key to Change Setting...");

this basicly becomes

wchar_t Message[] = ((wchar_t *)L"Press a Key to Change Setting..."));

And now I get the gcc error: initializer fails to determine size of
`Message'

That's right. You're defining an array without specifying the size. This
is only possible if the compiler can determine the size from the
initializer. But the intializer is a pointer. Why do you cast the
literal into a pointer?
I have tried casting to wchar_t[] but that gives it's own error.

You cannot cast into an array, especially not into one without a size.

You can if the compiler allows it. You have a literal of a size that
can be determined. Cast it to something else and the size can be
determined from simple math. String literals themselves are hacks
where they should be declared as: { 'h', 'e', 'l', 'l', 'o', '\n'}.;

Because templaces are an ugly mistake and I'd rather go back to C or
take up C# to avoid them but only if I'm forced to though it would be
easier to hack gcc to suppot it again with a command line option.

I'd just like to know if there is a way before I do anything that
drastic.
Why unsigned?

Who knows. Why not? You never heard of programs that assume char's
are unsigned? Unsigned char are more logical. If I decide I want
unsigned chars why should a programming languaged work against me?
Why do all your types SHOUT?

Because they started life as defines. Also because it makes them
easier to see compared to variable names. . That's only a small
portion of the code. I have redefined all types this way. I have use
INT and I can choose the it's size. It's also confined them to a
namespace so the global namespace isn't polluted and god forbid you
have to use some of my code you could comparmentalize it. But
ultimetly I just like it take way.

I suppose next your going to critisize my indentation style and go
into how c++ in the future will evolve to force everyone to use your
style...
 
O

Old Wolf

Why are you casting?
Take a look at the code. I'm abstracting strings.

I do it so I can construct strings of any datatype.

I think you mean "arrays of any char type". In C++, the word "string"
has the connotation of a container class of a char type,
instead of a pointer in C.
I have TCHAR String = TEXT("Hello World\n") so the code is written and

XTYPE::TCHAR presumably
If you have TCHAR in the global namespace (eg. if you import XTYPE
to global ns) you will run into a problem (more info below).
I can choose at compile time if I want the application to use ASCII by
default or unicode.

Obviously. But this does not require casting.
You said:
#define ASCII_TEXT(x) ((XTYPE::ACHAR *)(x))
#define UNICODE_TEXT(x) ((XTYPE::UCHAR *)(L##x))

Instead you should write:

#define ASCII_TEXT(x) x
#define WIDE_TEXT(x) L##x

Note - wchar_t is NOT unicode, if you do not understand
the difference you should go and do some googling.

Also, you have used many names that are confusingly similar to
different conventions; if you ever intend someone else to look
at your code then you might want to rethink them:
typedef char ACHAR ;
typedef wchar_t UCHAR ;

UCHAR is sometimes used as a typedef for "unsigned char"
typedef CHAR * STRING ;

Calling a pointer a string is confusing (especially in C++)
I suggest PCHAR instead
typedef CONST STRING CSTRING ;

Reminiscent of "CString" (a string class in Microsoft compilers)
and more obfuscated than "const STRING"
(You haven't defined CONST anywhere, so I can only assume that
you mean "const")
typedef CHAR TCHAR ;

TCHAR is defined in MS Windows (to be "char" if in ascii mode,
or "wchar_t" if in unicode mode). If anyone ever tries to port
your code to MS Windows they will run into this problem.

Note that what you are trying to do has already been done, in a
way that works (if with a few problems) and is understood by
the unwashed masses of MS Windows coders; see if you can
get hold of "tchar.h" and study it or appropriate certain parts of it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,161
Messages
2,570,892
Members
47,426
Latest member
MrMet

Latest Threads

Top