473,796 Members | 2,476 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

m##__LINE__

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
9 2343
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****@francen et.fr> wrote in message
news:fg******** *************** ***@news.free.f r... 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
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
Serge Paccalin <sp@mailclub.no .spam.net.inval id> 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,200 0,2002);S(1001, 1003,2001,2003) ;
S(2000,2001,400 0,3001);S(2002, 2003,3002,4003) ;
S(3001,3002,400 1,4002);
const int t[] = {M_(4000),M_(40 01),M_(4002),M_ (4003)};

#include<stdio. h>
int main(void)
{int j;
for(j=sizeof t/sizeof*t;j;)pri ntf("%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
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
Chris Dollin <ke**@hpl.hp.co m> 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
Chris Dollin <ke**@hpl.hp.co m> 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
Francois Grieu wrote:
Serge Paccalin <sp@mailclub.no .spam.net.inval id> 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
Kevin Bagust wrote:
Francois Grieu wrote:
Serge Paccalin <sp@mailclub.no .spam.net.inval id> 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
Kevin Bagust <ke**********@n tlworld.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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
2377
by: Imre | last post by:
Is there a Visual C++ newsgroup? I guess this question should go there, but I couldn't find it. Please take a look at the following little program: template <int Line> struct Test { enum { value = Line }; };
4
8370
by: Dom Gilligan | last post by:
Is there any way to get the preprocessor to produce the current line number in double quotes? At first sight, gcc seems to replace __LINE__ last (which would make sense), and so won't replace it at all if it's preceded by '#'. Background: I want to produce a string giving the current file and line number in an array of structures, as follows: ---------------
1
6948
by: Spry | last post by:
Hi, I wanted to write macros for finding the number of memory allocations and deallocations also wanted to find the locations. The code I have is a pretty big one. I have a wrapper on top of malloc(int x) as Xmalloc(int x) Now I want to write a macro for Xmalloc which can log the location of the file and the line and the number of bytes allocated.
18
11396
by: Paul Shipley | last post by:
Hi, Does anyone know a way of converting the __LINE__ macro to a string at compile time? The reason I ask it because I want to put some debug information in to tell me if memory is not being allocated. For example, this function will return the status of my system: static char* get_status (void) { char* str_ptr;
5
12094
by: jake1138 | last post by:
I couldn't find an example of this anywhere so I post it in the hope that someone finds it useful. I believe this is compiler specific (I'm using gcc), as C99 defines __VA_ARGS__. Comments are welcome. This will print the file name and line number followed by a format string and a variable number of arguments. The key here is that you MUST have a space between __LINE__ and the last comma, otherwise __LINE__ gets eaten by the ## if...
5
1791
by: Carlos | last post by:
I have a macro #define DIE(msg) do { fprintf(stderr, "%s (l.%d)\n", msg, __LINE__);\ exit(1); }\ while (0) and it works :). But later I thought, that if I use it like this: s = malloc(2000); if (!s) DIE("malloc failed!");
5
579
by: Generic Usenet Account | last post by:
Can someone kindly explain why stringification of the compiler preprocessor macro __LINE__ requires two steps, instead of one? I wanted to pass the error location of a system call to perror() and I found that I had to use a kludgy way to stick in the line number. Thanks, Song ///// Code Snippet ///// #include <stdio.h>
5
3370
by: Neo | last post by:
Hie, Can I put __FILE__ and __LINE__ macros inside the class function which may not be inline. And void function() { classobject::LogInfo(...); } Internally LogInfo should log file name and line number. Here I dont
3
14570
by: travis.downs | last post by:
Hi, I'm trying to use a macro to create a unique temporary variable name, such as #define TEMP_OBJ(string) MyType obj_ <some magic here(string); So something like TEMP_OBJ("foo")
0
10457
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10231
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
10013
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7550
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5443
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5576
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4119
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3733
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2927
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.