[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.c

Variable name that contains line number

Alex Vinokur

7/6/2011 10:29:00 AM

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



8 Answers

Michael DOUBEZ

7/6/2011 11:06:00 AM

0

On Jul 6, 12:29 pm, Alex Vinokur <alex.vino...@gmail.com> wrote:
> 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__)

--
Michael DOUBEZ

Alex Vinokur

7/6/2011 11:18:00 AM

0

On Jul 6, 2:06 pm, Michael DOUBEZ <michael.dou...@free.fr> wrote:
....
>
> #define PCAT( x, y)  x##y
> #define SET_VAR_NNN(n)  int PCAT(var,n)
> #define SET_VAR SET_VAR_NNN(__LINE__)
>
....

Thanks

Puppet_Sock

7/6/2011 1:41:00 PM

0

On Jul 6, 7:17 am, Alex Vinokur <alex.vino...@gmail.com> wrote:
> On Jul 6, 2:06 pm, Michael DOUBEZ <michael.dou...@free.fr> wrote:
> ...
>
> > #define PCAT( x, y)  x##y
> > #define SET_VAR_NNN(n)  int PCAT(var,n)
> > #define SET_VAR SET_VAR_NNN(__LINE__)
>
> ...
>
> 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/...

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

Juha Nieminen

7/6/2011 3:26:00 PM

0

In comp.lang.c++ Puppet_Sock <puppet_sock@hotmail.com> wrote:
> 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.

gw7rib

7/6/2011 9:28:00 PM

0

On Jul 6, 12:06 pm, Michael DOUBEZ <michael.dou...@free.fr> wrote:
> On Jul 6, 12:29 pm, Alex Vinokur <alex.vino...@gmail.com> wrote:
>
> > 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__)

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.

Shao Miller

7/6/2011 9:58:00 PM

0

On Wed, 6 Jul 2011 14:27:58 -0700 (PDT), Paul N <gw7rib@aol.com>
wrote:
> On Jul 6, 12:06 pm, Michael DOUBEZ <michael.dou...@free.fr> wrote:


> 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.

What happens if you allow for two substitutions per line?

Alexander Bartolich

7/7/2011 1:50:00 AM

0

Paul N wrote:
> On Jul 6, 12:06 pm, Michael DOUBEZ <michael.dou...@free.fr> wrote:
>>
>> #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?

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".

--
host -t mx moderators.isc.org

Shao Miller

7/7/2011 10:21:00 PM

0

On 7/6/2011 17:27, Paul N wrote:
> On Jul 6, 12:06 pm, Michael DOUBEZ<michael.dou...@free.fr> wrote:
>>
>> #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.

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)! :)