[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

preprocessor and character literal ('#letter'

Boris Dušek

11/1/2008 12:01:00 AM

Hi,

I have trouble defining a macro - see the following code:

#define LETTER_STRAIGHT(let) let = L'#let'

enum Letter {
LETTER_STRAIGHT(A),
LETTER_STRAIGHT(B),
LETTER_STRAIGHT(C),
};

I want it to expand to this:

enum Letter {
A = L'A',
B = L'B',
C = L'C',
};

However looking at the preprocessing output, it expands to this:

enum Letter {
A = L'#let',
B = L'#let',
C = L'#let',
};

How do I achieve the expansion in the way I want?

Thanks, Boris
6 Answers

dascandy@gmail.com

11/1/2008 8:33:00 AM

0

On Nov 1, 1:00 am, Boris Dušek <boris.du...@gmail.com> wrote:
> #define LETTER_STRAIGHT(let) let = L'#let'
>
<snip>
>
> enum Letter {
>     A = L'#let',
>     B = L'#let',
>     C = L'#let',
>
> };

You could try

#define LETTER_STRAIGHT(let) let = L#let[0]

which should create
> enum Letter {
> A = L"A"[0],
> B = L"B"[0],
> C = L"C"[0],
>
> };

which should be functionally equivalent. You can't create a single
char with preprocessor macros - it's always a string. You can then use
the first char of that string, iirc.

James Kanze

11/1/2008 8:57:00 AM

0

On Nov 1, 9:32 am, "dasca...@gmail.com" <dasca...@gmail.com> wrote:
> On Nov 1, 1:00 am, Boris Dušek <boris.du...@gmail.com> wrote:

> > #define LETTER_STRAIGHT(let) let = L'#let'

> <snip>

> > enum Letter {
> >     A = L'#let',
> >     B = L'#let',
> >     C = L'#let',
> > };

> You could try

> #define LETTER_STRAIGHT(let) let = L#let[0]

> which should create

> > enum Letter {
> >     A = L"A"[0],
> >     B = L"B"[0],
> >     C = L"C"[0],
> > };

> which should be functionally equivalent. You can't create a
> single char with preprocessor macros - it's always a string.
> You can then use the first char of that string, iirc.

You can, but the result of a dereferce operator is never a
constant expression, even if you're dereferencing a string
literal, so it can't be used as the initializer of an enum
constant (or an array dimension, or a template argument).

There are a number of different work-arounds possible, but
without knowing what problem he's trying to solve, it's
difficult to recommand any. Off hand, I don't see what the
problem is in writing:

enum Letter
{
A = L'A',
B = L'B',
C = L'C'
} ;

directly.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Juha Nieminen

11/1/2008 9:50:00 AM

0

James Kanze wrote:
> Off hand, I don't see what the
> problem is in writing:
>
> enum Letter
> {
> A = L'A',
> B = L'B',
> C = L'C'
> } ;
>
> directly.

Maybe he is trying to abstract the precise character type (L) away?

Boris Dušek

11/1/2008 10:10:00 AM

0

> > #define LETTER_STRAIGHT(let) let = L#let[0]
> > which should create
> > > enum Letter {
> > >     A = L"A"[0],
> > >     B = L"B"[0],
> > >     C = L"C"[0],
> > > };
> > which should be functionally equivalent. You can't create a
> > single char with preprocessor macros - it's always a string.
> > You can then use the first char of that string, iirc.
>
> You can, but the result of a dereferce operator is never a
> constant expression

Right, the compiler complains about that.

> difficult to recommand any.  Off hand, I don't see what the
> problem is in writing:
>
>     enum Letter
>     {
>         A = L'A',
>         B = L'B',
>         C = L'C'
>     } ;
>
> directly.

I had to write something like 100 enum values, so having a macro that
saves typing (if you copy/paste the line 100 times and then just
change one letter) and that helps avoiding a mistake that would result
from forgetting to change the right-hand side when I changed the left-
hand side is a plus. But I used vim to easily change it to the
explicit form, now it of course works.

What I am doing is that I want to include Unicode codepoints for all
letters in Czech alphabet (i.e. asides from English alphabet, 15 more
like ešcržýáíé) into the enum, and then define uppercasing,
lowercasing and asciifying (é -> e) tables using these enum values
rather than the codepoints directly. I want to avoid relying on cs_CZ
or Czech locale, since i.e. Mac OS X's support for locale is basically
non-existent (i.e. even std::locale("") throws std::runtime_error; the
same for std::locale("cs_CZ") or any other even if it is present in /
usr/share/locale). So I have to have my own conversion tables. And
btw., the goal of all of this is to write an app that tries its best
to deasciify an asciified text.

Thanks to both of you for your ideas,
Boris

James Kanze

11/2/2008 4:15:00 PM

0

On Nov 1, 11:09 am, Boris Dušek <boris.du...@gmail.com> wrote:
> > > #define LETTER_STRAIGHT(let) let = L#let[0]
> > > which should create
> > > > enum Letter {
> > > >     A = L"A"[0],
> > > >     B = L"B"[0],
> > > >     C = L"C"[0],
> > > > };
> > > which should be functionally equivalent. You can't create
> > > a single char with preprocessor macros - it's always a
> > > string. You can then use the first char of that string,
> > > iirc.

> > You can, but the result of a dereferce operator is never a
> > constant expression

> Right, the compiler complains about that.

> > difficult to recommand any.  Off hand, I don't see what the
> > problem is in writing:

> >     enum Letter
> >     {
> >         A = L'A',
> >         B = L'B',
> >         C = L'C'
> >     } ;

> > directly.

> I had to write something like 100 enum values, so having a
> macro that saves typing (if you copy/paste the line 100 times
> and then just change one letter) and that helps avoiding a
> mistake that would result from forgetting to change the
> right-hand side when I changed the left- hand side is a plus.
> But I used vim to easily change it to the explicit form, now
> it of course works.

Exactly. Any decent editor will be able to handle this.

> What I am doing is that I want to include Unicode codepoints
> for all letters in Czech alphabet (i.e. asides from English
> alphabet, 15 more like ì¹èø¾ýáíé) into the enum, and then
> define uppercasing, lowercasing and asciifying (é -> e) tables
> using these enum values rather than the codepoints directly.

That actually sounds like a pretty reasonable thing to do. I'd
write a simple AWK script, however, to generate the whole thing
from a simple two column list: the wide character and its ascii
equivalent.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Alexey Stepanyan

11/2/2008 8:25:00 PM

0

On 1 ????, 03:00, Boris Dušek <boris.du...@gmail.com> wrote:
> Hi,
>
> I have trouble defining a macro - see the following code:
>
> #define LETTER_STRAIGHT(let) let = L'#let'
>
> enum Letter {
>     LETTER_STRAIGHT(A),
>     LETTER_STRAIGHT(B),
>     LETTER_STRAIGHT(C),
>
> };
>
> I want it to expand to this:
>
> enum Letter {
>     A = L'A',
>     B = L'B',
>     C = L'C',
>
> };
>
> However looking at the preprocessing output, it expands to this:
>
> enum Letter {
>     A = L'#let',
>     B = L'#let',
>     C = L'#let',
>
> };
>
> How do I achieve the expansion in the way I want?
>
> Thanks, Boris

There is a Microsoft specific solution - charizing operator:
#define LETTER_STRAIGHT(let) let = L#@let

Thanks, Alexey.