Variable name that contains line number

A

Alex Vinokur

Hi,

---------------------------------
#define SET_VAR_NNN(n) int var##n
#define SET_VAR SET_VAR_NNN(__LINE__)

int main()
{
SET_VAR; // Line-6
SET_VAR; // Line-7

return 0;
}
---------------------------------

Of course, preprocessor generates

int main()
{
int var__LINE__;
int var__LINE__;
return 0;
}

I need

int main()
{
int var6;
int var7;
return 0;
}


Is it possible?

Thanks

Alex
 
M

Michael DOUBEZ

Hi,

---------------------------------
#define SET_VAR_NNN(n)  int var##n
#define SET_VAR SET_VAR_NNN(__LINE__)

int main()
{
        SET_VAR;   // Line-6
                SET_VAR;   // Line-7

        return 0;}

---------------------------------

Of course, preprocessor generates

int main()
{
        int var__LINE__;
        int var__LINE__;
        return 0;

}

I need

int main()
{
        int var6;
        int var7;
        return 0;

}

Is it possible?

Yes

#define PCAT( x, y) x##y
#define SET_VAR_NNN(n) int PCAT(var,n)
#define SET_VAR SET_VAR_NNN(__LINE__)
 
P

Puppet_Sock

...

Thanks

Of course, you should know that any reasonable
person who reviews your code will find it just
totally barf-worthy.

http://oilersnation.com/2010/11/23/gdb-200

And not in a good way.

Why on earth would you want a variable that
had the line number in its name? How do you
plan to refer to it from other lines?

Plus, any time I see that ## thing, my eye
starts to twitch.
Socks
 
J

Juha Nieminen

In comp.lang.c++ Puppet_Sock said:
Why on earth would you want a variable that
had the line number in its name? How do you
plan to refer to it from other lines?

Maybe he's making an IOCCC entry?
Plus, any time I see that ## thing, my eye
starts to twitch.

There are a few situations where the preprocessor can be used for code
generation to simplify the program (avoid repetition, make it easier to
read and understand), and where templates won't do. In some cases the ##
operator helps in doing that.
 
P

Paul N

Yes

#define PCAT( x, y)  x##y
#define SET_VAR_NNN(n)  int PCAT(var,n)
#define SET_VAR SET_VAR_NNN(__LINE__)

When I saw this question, I suspected the answer would be along those
lines, but I'm afraid I still can't see why the second form works and
the first form doesn't. Could someone explain to me?

In my naive way, I would expect the preprocessor to either substitute
the arguments and then the functions, or vice versa. So I would have
expected either the first version to work as follows:

SET_VAR; becomes
SET_VAR_NNN(__LINE__); becomes
SET_VAR_NNN(6); becomes
var##6; becomes
var6;

(ie first version works)

or for the second version to go:

SET_VAR; becomes
SET_VAR_NNN(__LINE__); becomes
int PCAT(var,__LINE__); becomes
int var##__LINE__; becomes
int var__LINE__;

(ie second version doesn't work).

I can't see what magic it must do to allow the frst form not to work
but the second to work. I've had a quick look at both the Standard and
the FAQ, but the penny hasn't dropped.

Thanks for any help.
Paul.
 
B

Balog Pal

Puppet_Sock said:
Why on earth would you want a variable that
had the line number in its name?

It is not uncommon that you need dummy-named object just to run its ctor at
the spot, and dtor at end of current scope. Line number is not really
needed just an unique identifier.
How do you plan to refer to it from other lines?

Those are not referred anywhere.
 
A

Alexander Bartolich

Paul said:
When I saw this question, I suspected the answer would be along those
lines, but I'm afraid I still can't see why the second form works and
the first form doesn't. Could someone explain to me?

Macro substitution and parameter substitution are two different things.
Consider this example:

#define FOO EXIT_SUCCESS
return FOO;

Here the pre-processor must recursively substitute all definitions
or the C compiler will complain.

Parameter substitution, on the other hand, must be a bit lazy, or
operators # and ## would stop working. A contrived example:

const char* GetExitName(int n)
{
#define CASE(n) case n: return #n;
switch(n)
{
CASE(EXIT_SUCCESS)
CASE(EXIT_FAILURE)
default: return 0;
}
#undef CASE
}

Fully recursive substitution of parameters would result in code
that would return "0" (or whatever value EXIT_SUCCESS has on your
platform) instead of "EXIT_SUCCESS".
 
S

Shao Miller

When I saw this question, I suspected the answer would be along those
lines, but I'm afraid I still can't see why the second form works and
the first form doesn't. Could someone explain to me?

In my naive way, I would expect the preprocessor to either substitute
the arguments and then the functions, or vice versa. So I would have
expected either the first version to work as follows:

SET_VAR; becomes
SET_VAR_NNN(__LINE__); becomes
SET_VAR_NNN(6); becomes
var##6; becomes
var6;

(ie first version works)

or for the second version to go:

SET_VAR; becomes
SET_VAR_NNN(__LINE__); becomes
int PCAT(var,__LINE__); becomes
int var##__LINE__; becomes
int var__LINE__;

(ie second version doesn't work).

I can't see what magic it must do to allow the frst form not to work
but the second to work. I've had a quick look at both the Standard and
the FAQ, but the penny hasn't dropped.

The relevant portions of the Standard might be 6.10.3.3p2, 6.10.3.3p3,
6.10.3.4, if I understand them correctly.

SET_VAR
/* Replacement list */
SET_VAR_NNN(__LINE__)
/* Rescan finds 'SET_VAR_NNN()' and substitutes replacement list */
int PCAT(var,n)
/* Argument substitution "all macros contained therein" */
__LINE__
6
/* Argument substitution "after" */
int PCAT(var,6)
/* Rescan finds 'PCAT()' and substitutes replacement list*/
x##y
/* "...preceded or followed by a ##..." */
var6
/* Rescan finds nothing */

Contrast with the original:

SET_VAR
/* Replacement list */
SET_VAR_NNN(__LINE__)
/* Rescan finds 'SET_VAR_NNN()' and substitutes replacement list */
int var##n
/* "...preceded or followed by a ##..." */
int var__LINE__
/* Rescan finds nothing */

I hope this helps (and hope it doesn't contain an error)! :)
 

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,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top