single-quoting a macro argument

M

Marius Lazer

Is it possible to write a macro that single-quotes its argument?

#define SOME_MACRO(x)

such that SOME_MACRO(foo) expands to 'foo'

Thanks,
Marius
 
S

SM Ryan

# Is it possible to write a macro that single-quotes its argument?
#
# #define SOME_MACRO(x)
#
# such that SOME_MACRO(foo) expands to 'foo'

For a single character you can do
#define LITERAL(x) (*#x)
and perhaps the compiler can optimise away the memory reference.

For multiple characters, you might be able to get away with some like
#define LITERAL(x) (*((int*)#x "\0\0\0\0\0\0\0\0"))
but that's making assumptions about how the compiler stores strings.

Unless there's particular reason you need to make a constant,
you can do something like
int literalise(char *s) {
int i,v; unsigned char *u = (unsigned char*)s;
for (i=0,v=0; u && i<sizeof v; i++)
v = (v<<CHAR_BIT) | u
return v;
}
literalise("foo");
which also avoids implementation dependent interpretation of
multi-character literals, endianess, and memory alignment
questions.
 
M

Marius Lazer

I meant literally expansion to 'foo', not to it's first character.
There are no value semantics here.

#define SOME_MACRO(x) #x

SOME_MACRO(foo) expands to "foo" but I need 'foo'

I tried something like this which is close but not exactly what I need:

#define QUOTE '
#define SOME_MACRO(x) QUOTE x QUOTE

SOME_MACRO(foo) expands to ' foo ' (with spaces instead of 'foo').

Thanks,
Marius
 
B

Ben Pfaff

Marius Lazer said:
I meant literally expansion to 'foo', not to it's first character.
There are no value semantics here.

#define SOME_MACRO(x) #x

SOME_MACRO(foo) expands to "foo" but I need 'foo'

I don't think you can get what you want from the C preprocessor.
 
J

Joe Smith

Ben Pfaff said:
I don't think you can get what you want from the C preprocessor.

If you could torture the preprocessor into doing this, I would claim that it
acted under duress. This is processing. joe
 
K

Kenneth Brody

Marius Lazer wrote:
[...]
#define QUOTE '
#define SOME_MACRO(x) QUOTE x QUOTE
[...]

Is MSVC broken, or is this a valid error?

===== usenet.c
#define QUOTE '
=====

Attempting to pre-process this one-line file gives me:

usenet.c(1) : error C2001: newline in constant

===== usenet.c
#define QUOTE \'
=====

This gives:

usenet.c(1) : error C2295: escaped ''' : is illegal in macro definition

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:[email protected]>
 
D

David Resnick

Marius said:
I meant literally expansion to 'foo', not to it's first character.
There are no value semantics here.

#define SOME_MACRO(x) #x

SOME_MACRO(foo) expands to "foo" but I need 'foo'

I tried something like this which is close but not exactly what I need:

#define QUOTE '
#define SOME_MACRO(x) QUOTE x QUOTE

SOME_MACRO(foo) expands to ' foo ' (with spaces instead of 'foo').

Thanks,
Marius

why not

#define SOME_MACRO(x) 'x'

Seems to me to work, unless I don't understand what you want. What I
see:

temp(1267)$ cat foo.c
#define SOME_MACRO(x) 'x'

int main(void)
{
SOME_MACRO(a);

return 0;
}

temp(1268)$ gcc -o foo -E foo.c
temp(1269)$ cat foo
# 1 "foo.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "foo.c"


int main(void)
{
'x';

return 0;
}




-David
 
K

Kenneth Brody

David Resnick wrote:
[...]
why not

#define SOME_MACRO(x) 'x'

Seems to me to work, unless I don't understand what you want. What I
see:

temp(1267)$ cat foo.c
#define SOME_MACRO(x) 'x' [...]
SOME_MACRO(a);
[...]
'x';

Didn't you notice a problem with the macro expansion here?

[...]

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:[email protected]>
 
D

David Resnick

David said:
why not

#define SOME_MACRO(x) 'x'

Seems to me to work, unless I don't understand what you want. What I
see:

temp(1267)$ cat foo.c
#define SOME_MACRO(x) 'x'

int main(void)
{
SOME_MACRO(a);

return 0;
}

temp(1268)$ gcc -o foo -E foo.c
temp(1269)$ cat foo
# 1 "foo.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "foo.c"


int main(void)
{
'x';

return 0;
}




-David

OK, I'm a moron. I looked at that and thought it worked.

-David
 
D

David Resnick

Kenneth said:
David Resnick wrote:
[...]
why not

#define SOME_MACRO(x) 'x'

Seems to me to work, unless I don't understand what you want. What I
see:

temp(1267)$ cat foo.c
#define SOME_MACRO(x) 'x' [...]
SOME_MACRO(a);
[...]
'x';

Didn't you notice a problem with the macro expansion here?

[...]

Post in haste, repent at leisure.

-David
 
R

Robert Gamble

Marius said:
Is it possible to write a macro that single-quotes its argument?

#define SOME_MACRO(x)

such that SOME_MACRO(foo) expands to 'foo'

I *think* this is Standard, someone will correct me if its not:

#define QUOTE(x) '
#define foo2(x) x
#define foo(x) QUOTE(x)foo2(x)QUOTE(x)

foo(test)

Is this just for academic purposes or is there actually a reason you
can't say 'test'?

Robert Gamble
 
A

Andrew Poelstra

I *think* this is Standard, someone will correct me if its not:

#define QUOTE(x) '
#define foo2(x) x
#define foo(x) QUOTE(x)foo2(x)QUOTE(x)

foo(test)

Is this just for academic purposes or is there actually a reason you
can't say 'test'?

Also, what use is it to have a string in single quotes? My compiler
invariably gives me warnings if I try to do such a thing.
 
B

Ben Pfaff

Robert Gamble said:
I *think* this is Standard, someone will correct me if its not:

#define QUOTE(x) '

No, it's not, on the basis of that line alone. The replacement
list in a macro definition must be a sequence of preprocessing
tokens. A lone single-quote is not a valid preprocessing token.
In fact C99 section 6.4 explicitly disallows the possibility:

preprocessing-token:
header-name
identifier
pp-number
character-constant
string-literal
punctuator
each non-white-space character that cannot be one of the above

....

The categories of preprocessing tokens are: header names,
identifiers, preprocessing numbers, character constants,
string literals, punctuators, and single non-white-space
characters that do not lexically match the other
preprocessing token categories.58) If a ' or a " character
matches the last category, the behavior is undefined.
 
K

Keith Thompson

Robert Gamble said:
I *think* this is Standard, someone will correct me if its not:

#define QUOTE(x) '
#define foo2(x) x
#define foo(x) QUOTE(x)foo2(x)QUOTE(x)

foo(test)

Interesting. That seems to work on at least one compiler, but I
believe it invokes undefined behavior. The source file is decomposed
into preprocessing tokens in translation phase 3; preprocessing
directives and macros are handled in phase 4. C99 6.4 defines
preprocessing tokens:

The categories of preprocessing tokens are: header names,
identifiers, preprocessing numbers, character constants, string
literals, punctuators, and single non-white-space characters that
do not lexically match the other preprocessing token
categories. If a ' or a " character matches the last category, the
behavior is undefined.
 
C

CBFalconer

Andrew said:
.... snip ...

Also, what use is it to have a string in single quotes? My compiler
invariably gives me warnings if I try to do such a thing.

My Pascal compiler doesn't :)

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
 
M

Marius Lazer

Robert said:
I *think* this is Standard, someone will correct me if its not:

#define QUOTE(x) '
#define foo2(x) x
#define foo(x) QUOTE(x)foo2(x)QUOTE(x)

foo(test)

Is this just for academic purposes or is there actually a reason you
can't say 'test'?

No, it's not at all academic. I'm trying to generate repetitive Oracle
and Ingres select statements using macros so I don't have to type this
a million times.

Anyway, this does it (I tried it on gcc 4.0.2).

Thanks Robert!
Marius
 
K

Keith Thompson

Marius Lazer said:
No, it's not at all academic. I'm trying to generate repetitive Oracle
and Ingres select statements using macros so I don't have to type this
a million times.

So you're using the C preprocessor to produce code in a language other
than C?

Have you considered using some other preprocessor? (m4, maybe?)
Anyway, this does it (I tried it on gcc 4.0.2).

If the fact that it happens to work on one specific implementation is
good enough for you, that's fine. You should just be aware that it
invokes undefined behavior, and it could easily fail in arbitrarily
bad and subtle ways under other implementations.
 
R

Robert Gamble

Keith said:
Interesting. That seems to work on at least one compiler, but I
believe it invokes undefined behavior. The source file is decomposed
into preprocessing tokens in translation phase 3; preprocessing
directives and macros are handled in phase 4. C99 6.4 defines
preprocessing tokens:

The categories of preprocessing tokens are: header names,
identifiers, preprocessing numbers, character constants, string
literals, punctuators, and single non-white-space characters that
do not lexically match the other preprocessing token
categories. If a ' or a " character matches the last category, the
behavior is undefined.

Okay, so much for that. Although I suspect it will work on many
translators it obviously isn't Standard conforming. After searching
comp.std.c on the topic I am convinced there is no Standard solution.

Robert Gamble
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
474,183
Messages
2,570,969
Members
47,524
Latest member
ecomwebdesign

Latest Threads

Top