By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,562 Members | 1,298 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,562 IT Pros & Developers. It's quick & easy.

m##__LINE__

P: n/a
Hello,

I wrote this:

#define M(x) enum { m##__LINE__ = x };
#line 1000
M(126)
M(341)
M(565)
...

expecting the preprocessor to build

enum { m1000 = 126 };
enum { m1001 = 341 };
enum { m1002 = 565 };
...

but instead got

enum { m__LINE__ = 126};
enum { m__LINE__ = 341};
enum { m__LINE__ = 565};
...

which of course did not copile.

Is there any solution to produce the expected result,
without entering the a sequence like 1000 1001 1002.. ?

I tried

#define M(l,x) enum { m##l = x };
#line 1000
M(__LINE__,126)
M(__LINE__,341)
M(__LINE__,565)
...

and similarly failed.

Note: I do not want to put these values into an array; I want
them as enum, which allows me to sort them using the compiler
with a sorting network, rather than at runtime.
TIA,

François Grieu
Nov 15 '05 #1
Share this Question
Share on Google+
9 Replies


P: n/a
sat

Hi Francois
lets assume that we do end up creating preprocessed enums like what you
have mentioned here. But, what are you trying to achieve by such a thing.
You would end up with
enum { m1000 = 126 };
enum { m1001 = 341 };
enum { m1002 = 565 };
which are generated before compile time, but how are you going to access
them in the code.. How do you know if 126 was the first (1000) enum and 341
was the second ( 1001) enum..
May be if you give the use case it would be easier to look at it and
appreciate the whole effort ..
sat
"Francois Grieu" <fg****@francenet.fr> wrote in message
news:fg**************************@news.free.fr... Hello,

I wrote this:

#define M(x) enum { m##__LINE__ = x };
#line 1000
M(126)
M(341)
M(565)
..

expecting the preprocessor to build

enum { m1000 = 126 };
enum { m1001 = 341 };
enum { m1002 = 565 };
..

but instead got

enum { m__LINE__ = 126};
enum { m__LINE__ = 341};
enum { m__LINE__ = 565};
..

which of course did not copile.

Is there any solution to produce the expected result,
without entering the a sequence like 1000 1001 1002.. ?

I tried

#define M(l,x) enum { m##l = x };
#line 1000
M(__LINE__,126)
M(__LINE__,341)
M(__LINE__,565)
..

and similarly failed.

Note: I do not want to put these values into an array; I want
them as enum, which allows me to sort them using the compiler
with a sorting network, rather than at runtime.
TIA,

François Grieu

Nov 15 '05 #2

P: n/a
Le mardi 11 octobre 2005 à 10:28:05, Francois Grieu a écrit dans
comp.lang.c*:
I wrote this:

#define M(x) enum { m##__LINE__ = x };
#line 1000
M(126)
M(341)
M(565)
..

expecting the preprocessor to build

enum { m1000 = 126 };
enum { m1001 = 341 };
enum { m1002 = 565 };
..

but instead got

enum { m__LINE__ = 126};
enum { m__LINE__ = 341};
enum { m__LINE__ = 565};


You need more macros to make sure __LINE__ is evaluated before being
glued to "m":

#define M__(l) m##l
#define M_(l) M__(l)
#define M(x) enum { M_(__LINE__) = x };

--
___________ 11/10/2005 13:10:12
_/ _ \_`_`_`_) Serge PACCALIN -- sp ad mailclub.net
\ \_L_) Il faut donc que les hommes commencent
-'(__) par n'être pas fanatiques pour mériter
_/___(_) la tolérance. -- Voltaire, 1763
Nov 15 '05 #3

P: n/a
Serge Paccalin <sp@mailclub.no.spam.net.invalid> wrote:
You need more macros to make sure __LINE__ is evaluated before
being glued to "m"


Many thanks, it works!
Anyone care to explain why THREE nested macros are necessary ?

#define M__(l) m##l
#define M_(l) M__(l)
#define M(x) enum { M_(__LINE__) = x };

#line 1000
M(565)
M(126)
M(341)
M(747)
enum {MustHave4Lines = 0/(__LINE__-1000==4)};

#define C(a,b) M_(a)>M_(b) // or another order
// for sorting networks, see TAOCP Vol 3
#define S(a,b,c,d) enum{M_(c)=C(a,b)?M_(a):M_(b),\
M_(d)=C(a,b)?M_(b):M_(a)};
S(1000,1002,2000,2002);S(1001,1003,2001,2003);
S(2000,2001,4000,3001);S(2002,2003,3002,4003);
S(3001,3002,4001,4002);
const int t[] = {M_(4000),M_(4001),M_(4002),M_(4003)};

#include<stdio.h>
int main(void)
{int j;
for(j=sizeof t/sizeof*t;j;)printf("%d\n",t[--j]);
return 0;}

François Grieu

PS: This is not an entry to the obfuscated C contest; I need
a table of constants sorted according to a such a complex
criteria that it is unpractical to sort it by hand, an I am
dealing with the limitations of an embedded platform, where
sorting in RAM is not an option.
Nov 15 '05 #4

P: n/a
Francois Grieu wrote:
PS: This is not an entry to the obfuscated C contest; I need
a table of constants sorted according to a such a complex
criteria that it is unpractical to sort it by hand, an I am
dealing with the limitations of an embedded platform, where
sorting in RAM is not an option.


Sort it by machine and generate C code.

--
Chris "electric hedgehog" Dollin
Essare - to be. Essen - to be at Messe Essen for SPIEL 05.
Nov 15 '05 #5

P: n/a
Chris Dollin <ke**@hpl.hp.com> wrote:
Sort it by machine and generate C code.


[OT] Yes, I did this previously, but I can't figure out
how to invoke an external tool and craft make rules within
the IDE (MW CW 4.2...) hosting the only known C compiler
for my target. And the table to sort changes several
times a day, during development, and I fear we forget to
invoke the sort tool.

So I decided to make a tool generating (once only)
C source code for a sorting network so that the C
compiler will do the job without an external tool.
Thanks to your trick, it is gona work ! And it's fun.
Francois Grieu
Nov 15 '05 #6

P: n/a
Chris Dollin <ke**@hpl.hp.com> wrote:
Sort it by machine and generate C code.


[OT] Yes, I did this previously, but I can't figure out
how to invoke an external tool and craft make rules within
the IDE (MW CW 4.2...) hosting the only known C compiler
for my target. And the table to sort changes several
times a day, during development, and I fear we forget to
invoke the sort tool.
So I decided to make a tool generating (once only)
C source code for a sorting network so that the C
compiler will do the job without an external tool.
Thanks to Serge's trick, it is gona work ! And it's fun.
Francois Grieu
Nov 15 '05 #7

P: n/a
Francois Grieu wrote:
Serge Paccalin <sp@mailclub.no.spam.net.invalid> wrote:
You need more macros to make sure __LINE__ is evaluated before
being glued to "m"


Many thanks, it works!
Anyone care to explain why THREE nested macros are necessary ?

#define M__(l) m##l
#define M_(l) M__(l)
#define M(x) enum { M_(__LINE__) = x };


IIRC With the following macros:

#define M_(l) m##l
#define M(x) enum { M_(__LINE__) = x };

the preprocessor will do the following sequence of replacements:
1) M(565)
2) enum { M_(__LINE__) = 565 }; /* Replace macro M and arguments */
3) enum { m##__LINE__ = 565 }; /* Replace macro M_ as next on line */
4) enum { m__LINE__ = 565 }; /* Process ## highest precedence */

Where as with the three macro version it will do the following:
1) M(565)
2) enum { M_(__LINE__) = 565 }; /* Replace macro M and arguments */
3) enum { M__(__LINE__) = 565 }; /* Replace macro M_ as next on line */
4) enum { M__(1001) = 565 }; /* Replace __LINE__ with the current
line number */
3) enum { m##1001 = 565 }; /* Replace macro M__ */
4) enum { m__LINE__ = 565 }; /* Process ## highest precedence */

So basically as soon as a preprocessor see a # or a ## in the current
stream of tokens to be preprocessed the very next thing that it will do
is to either convert the argument to a string or concatenate the two
arguments.

Kevin.
Nov 15 '05 #8

P: n/a
Kevin Bagust wrote:
Francois Grieu wrote:
Serge Paccalin <sp@mailclub.no.spam.net.invalid> wrote:
You need more macros to make sure __LINE__ is evaluated before
being glued to "m"

Many thanks, it works!
Anyone care to explain why THREE nested macros are necessary ?

#define M__(l) m##l
#define M_(l) M__(l)
#define M(x) enum { M_(__LINE__) = x };


IIRC With the following macros:

#define M_(l) m##l
#define M(x) enum { M_(__LINE__) = x };

the preprocessor will do the following sequence of replacements:
1) M(565)
2) enum { M_(__LINE__) = 565 }; /* Replace macro M and arguments */
3) enum { m##__LINE__ = 565 }; /* Replace macro M_ as next on line */
4) enum { m__LINE__ = 565 }; /* Process ## highest precedence */

Where as with the three macro version it will do the following:
1) M(565)
2) enum { M_(__LINE__) = 565 }; /* Replace macro M and arguments */
3) enum { M__(__LINE__) = 565 }; /* Replace macro M_ as next on line */
4) enum { M__(1001) = 565 }; /* Replace __LINE__ with the current
line number */
3) enum { m##1001 = 565 }; /* Replace macro M__ */
4) enum { m__LINE__ = 565 }; /* Process ## highest precedence */

Unfortunate copy/pasting here; last two lines should be

5) enum { m##1001 = 565 }; /* Replace macro M__ */
6) enum { m1001 = 565 }; /* Process ## */

S.
Nov 15 '05 #9

P: n/a
Kevin Bagust <ke**********@ntlworld.com> and Skarmander explained:
Francois Grieu wrote:
Anyone care to explain why THREE nested macros are necessary ?
When expanding
#define M_(l) m##l
#define M(x) enum { M_(__LINE__) = x };

the preprocessor will do the following sequence of replacements:
1) M(565)
2) enum { M_(__LINE__) = 565 }; /* Replace macro M and arguments */
3) enum { m##__LINE__ = 565 }; /* Replace macro M_ as next on line */
4) enum { m__LINE__ = 565 }; /* Process ## highest precedence */ but
#define M__(l) m##l
#define M_(l) M__(l)
#define M(x) enum { M_(__LINE__) = x };

this three macro version it will do the following:
1) M(565)
2) enum { M_(__LINE__) = 565 }; /* Replace macro M and arguments */
3) enum { M__(__LINE__) = 565 }; /* Replace macro M_ as next on line */
4) enum { M__(1001) = 565 }; /* Replace __LINE__ with current line nb */
5) enum { m##1001 = 565 }; /* Replace macro M__ */
6) enum { m1001 = 565 }; /* Process ## */


I now see the light. The M_ to M__ replacement delays reaching ## until
__LINE__ has been expanded. Clever. Is this par ANSI/ISO C89/90 ?
François Grieu
Nov 15 '05 #10

This discussion thread is closed

Replies have been disabled for this discussion.