String: "anti" string oprator

P

paragk

Hi,

The # operator converts a parameter to a string. Is there a way to
"anti" string?

For e.g.

char *p="abc";
char *q="xyz";

#define declare_fun(x) void <anti string>x( void)

main()
{

declare_func(*p);
declare_func(*q);
}

I would like to get the following after the preprocessor is run:

main()
{
void abc(void);
void xyz(void);
}

Is there a way to achieve this?

Thanks,
Parag
 
S

Seebs

The # operator converts a parameter to a string. Is there a way to
"anti" string?
No.

char *p="abc";
char *q="xyz";
#define declare_fun(x) void <anti string>x( void)

main()
{

declare_func(*p);
declare_func(*q);
}

I would like to get the following after the preprocessor is run:

main()
{
void abc(void);
void xyz(void);
}
Is there a way to achieve this?

No. You're trying to perform a runtime computation at compile time, and
you can't do it. You need an interpreted language, or at least one with
support for compiling new code at runtime.

-s
 
P

paragk

No.  You're trying to perform a runtime computation at compile time, and
you can't do it.  You need an interpreted language, or at least one with
support for compiling new code at runtime.

-s

How about:

main()
{
declare_func("abc");
declare_func("pqr");
}

Will this work?

Thanks,
Parag
 
K

Keith Thompson

paragk said:
How about:

main()
{
declare_func("abc");
declare_func("pqr");
}

Will this work?

I don't believe there's any way to get the proprocessor to convert
a string literal to an identifier.

Even if there were, what would be the point? Why not just write:

int main(void) /* note proper declaration of main */
{
declare_func(abc);
declare_func(pqr);
}

Or, for that matter:

int main(void)
{
void abc(void);
void pqr(void);
}

And in fact, it rarely makes sense to declare a function inside
another function. (*Defining* a function inside another function
is illegal, unless you're using some compiler-specific extension).

Generally declarations for functions not defined in the current
source file should be in header files that you can #include:

#include "abc_pqr.h" /* declare abc and pqr */
int main(void)
{
/* ... */
}

Exactly what problem are you trying to solve?
 
R

Rui Maciel

paragk said:
Hi,

The # operator converts a parameter to a string. Is there a way to
"anti" string?

For e.g.

char *p="abc";
char *q="xyz";

#define declare_fun(x) void <anti string>x( void)

main()
{

declare_func(*p);
declare_func(*q);
}

I would like to get the following after the preprocessor is run:

main()
{
void abc(void);
void xyz(void);
}

Is there a way to achieve this?


From your example, and noting that your intended result doesn't include
any string literal, it would be simpler to define the function-declaring
macro with a parameter intended to directly set that token. So, for
example:


<code>
#define declare_fun(x) void x( void)

declare_func(abc);
declare_func(xyz);
</code>

That would generate:
<code>
void abc(void);
void xyz(void);
</code>


If you really need to declare functions whose identifiers include a token
which is also present in a string literal then you can always define that
token separately and then include it in the declarations of both your
function and your string literals.


Rui Maciel
 
P

paragk

I don't believe there's any way to get the proprocessor to convert
a string literal to an identifier.

Even if there were, what would be the point?  Why not just write:

int main(void) /* note proper declaration of main */
{
    declare_func(abc);
    declare_func(pqr);

}

Or, for that matter:

int main(void)
{
    void abc(void);
    void pqr(void);

}

And in fact, it rarely makes sense to declare a function inside
another function.  (*Defining* a function inside another function
is illegal, unless you're using some compiler-specific extension).

Generally declarations for functions not defined in the current
source file should be in header files that you can #include:

#include "abc_pqr.h" /* declare abc and pqr */
int main(void)
{
    /* ... */

}

Exactly what problem are you trying to solve?

--
Keith Thompson (The_Other_Keith) (e-mail address removed)  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"


I have a function which takes a number of parameters. The parameter
names have a fixed template.

For e.g.

foo( int a, int b, int c)

I need to call foo() multiple times with the following arguments

foo( param_first, param_second, param_third);
foo( param1_first, param1_second, param1_third);
foo( test_first, test_second, test_third);

....

Lets assume the parameters are global variables.

I can have a table which lists all the parameters:

for e.g.

struct {

int first,
int second,
int third
} param_template

and then an array of this struct

[ {param_first, param_second, param_third},
{param1_first, param1_second, param1_third},
{test_first, test_second, test_third},
...
]


I can then iterate through this array and call foo().

I was thinking of having a array of strings and generating the
parameter names on the fly.

That is:

[ "param", "param1", "test"... ]

and then generate the parameter names on the fly and call foo()

I just realized this won't work.

A better approach would be to generate the static table.

#define GEN_TBL_ENTRY(x) { x##_first, x##_second, x##_third}

And then:

[ GEN_TBL_ENTRY(param),
GEN_TBL_ENTRY(param1),
GEN_TBL_ENTRY(test),
...
]


Thanks,
Parag
 
S

Seebs

seebs said:
How about:

Read that paragraph again. No change in punctuation will change the
essence of the problem, which is that you're trying to look at the contents
of a variable and use it as a symbol to compile at compile time.

On some systems there's ways to look up symbols that were already defined
by names, but there's no way to do this at compile time. Try an
intepreted language.

-s
 
K

Keith Thompson

paragk said:
How about:
 main()
 {
   declare_func("abc");
   declare_func("pqr");
 }
Will this work?

I don't believe there's any way to get the proprocessor to convert
a string literal to an identifier. [...]
Exactly what problem are you trying to solve?

I have a function which takes a number of parameters. The parameter
names have a fixed template.

For e.g.

foo( int a, int b, int c)

I need to call foo() multiple times with the following arguments

foo( param_first, param_second, param_third);
foo( param1_first, param1_second, param1_third);
foo( test_first, test_second, test_third);

If you only have one function to be called, why are you looking for
a macro that generates a function declaration? Just declare foo,
and you're done (at least with that part).
...

Lets assume the parameters are global variables.

Why are they global variables?
I can have a table which lists all the parameters:

for e.g.

struct {

int first,
int second,
int third
} param_template

and then an array of this struct

[ {param_first, param_second, param_third},
{param1_first, param1_second, param1_third},
{test_first, test_second, test_third},
...
]

If you have a series of objects, each of which is to be passed as the
first (, second, third) argument to foo(), perhaps the whole series
should just be declared as an array. Or maybe you should have an array
of structs, where each struct contains all three parameters.

Just declare your array(s) and loop over it. No need for any macros.

[snip]

Oh, and please snip some of the quoted text when you post a followup.
Just keep whatever is needed for the followup to make sense.
In particular, please don't quote signatures (the lines following
the "-- " delimiter).
 
J

James Kuyper

Hi,

The # operator converts a parameter to a string. Is there a way to
"anti" string?

More accurately, it generates a string literal. String literals are
features of your source code which cease to exist by the time your
program has been completely translated, whereas strings don't exist
until your program starts executing. Most string literals get translated
into code which causes the creation of a string when the program is
executed, which could cause some confusion about that distinction.
For e.g.

char *p="abc";
char *q="xyz";

#define declare_fun(x) void<anti string>x( void)

main()
{

declare_func(*p);
declare_func(*q);

Even if your idea were feasible to implement, I think you would want q,
not *q, in this location. q points at a string; *q is an expression with
a integer value of 'x'.
}

I would like to get the following after the preprocessor is run:

main()
{
void abc(void);
void xyz(void);
}

Is there a way to achieve this?

The fundamental problem is that p points at a string which does not
exist until the program starts executing, while declarations require
names that must be specified while the program is still being
translated. What you're asking for can only be done in a language that
is, by design, interpreted. I suspect that what you actually need is
something different from what you've asked for.

Something which could be done without turning C into an interpreted
language is to convert a string literal into a similar token, but
without the double quotes, making it usable as an identifier. However,
C's preprocessing features are not powerful enough to do something like
that. If you think you need that feature, I recommend trying to figure
out how you can reverse the organization of your code so you can start
with a token, and convert it to a string literal.
 
M

Marcin Grzegorczyk

Seebs said:
Read that paragraph again. No change in punctuation will change the
essence of the problem, which is that you're trying to look at the contents
of a variable and use it as a symbol to compile at compile time.

On some systems there's ways to look up symbols that were already defined
by names, but there's no way to do this at compile time. Try an
intepreted language.

As a matter of nitpick, it doesn't have to be an interpreted language.
D is an example of a compiled language which allows this sort of
'de-tokenization' of string constants, as well as compile-time string
operations like concatenation and substringing.

But, of course, none of that is available in standard C.
 
R

Rui Maciel

Marcin said:
As a matter of nitpick, it doesn't have to be an interpreted language.
D is an example of a compiled language which allows this sort of
'de-tokenization' of string constants, as well as compile-time string
operations like concatenation and substringing.

But, of course, none of that is available in standard C.

While we are in the process of picking nits, I believe that, in this
context, Seebs' reference to "compile time" was made regarding the
preprocessing stage. Considering this, it is not possible to look at the
contents of a variable which is defined through a grammar which your
parser (in this case the C preprocessor) either doesn't recognize as such
or simply ignores.

To put it in other words, in CPP terms a variable declaration/definition
in C is not a variable declaration at all. It is simply noise which
should be ignored. As a consequence, it doesn't exist and therefore it's
contents cannot be accessed.


Rui Maciel
 
J

James Kuyper

Seebs wrote: ....

As a matter of nitpick, it doesn't have to be an interpreted language. D
is an example of a compiled language which allows this sort of
'de-tokenization' of string constants, as well as compile-time string
operations like concatenation and substringing.

The OP's example was not trying to detokenize a string constant, it was
trying to make use of a variable declared as a pointer to char.
 
M

Marcin Grzegorczyk

James said:
The OP's example was not trying to detokenize a string constant, it was
trying to make use of a variable declared as a pointer to char.

Yes, but the OP also talked about “"anti" stringâ€, presumably meaning a
"destringization" operator ("de-tokenization" was a wrong word to use on
my part, sorry about that). And his second example did not involve any
variables.
 

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

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top