473,562 Members | 2,665 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

can preprocessor automatically make N array elements?

dan
I would like to have the preprocessor automatically generate the
number of array elements requested. Each element is zero. The elements
get pasted into a larger array. The other elements may be non-zero.

***** Here is an example of what I need to do:

#define YEAR_1 2005
#define YEAR_2 2007
#define YEARS (YEAR_2 - YEAR_1 + 1)

// Start missing steps (using ## operator in some way?)
// This is the part I can't figure out.

// I think the following definitions are probably needed in the
missing steps
// I'd like ZEROES_AND_COMM AS (YEARS) to get translated to one of them

#define ZEROES_AND_COMM AS_1 0
#define ZEROES_AND_COMM AS_2 0, 0
#define ZEROES_AND_COMM AS_3 0, 0, 0

// End missing steps

#define ARRAY_ELEMS_AGE 0, 1, 5, 10, 15, 20, 40, 60
#define ARRAY_ELEMS_YRS ZEROES_AND_COMM AS (YEARS)
#define ARRAY_ELEMS_EDU 0, 6, 8, 12, 16

int intArray [] = { ARRAY_ELEMS_AGE , ARRAY_ELEMS_YRS ,
ARRAY_ELEMS_EDU , };

// intArray ends up with { 0, 1, 5, 10, 15, 20, 40, 60, 0, 0, 0,
0, 6, 8, 12, 16, }

****** Here's one failed test program (does not compile)

#include <stdio.h>
#include <stdlib.h>

#define YEAR_1 2005
#define YEAR_2 2007
#define YEARS (YEAR_2 - YEAR_1 + 1)

#define CAT(x,y) x ## y
#define XCAT(x,y) CAT(x,y)

#define ZEROES_AND_COMM AS_1 0
#define ZEROES_AND_COMM AS_2 0, 0
#define ZEROES_AND_COMM AS_3 0, 0, 0

#define ZEROES_AND_COMM AS(n) XCAT(ZEROES_AND _COMMAS_, n)

main () {
int intArray [] = { ZEROES_AND_COMM AS (YEARS) };
printf ("Number of elements = %d\n", sizeof (intArray) / sizeof
(int));
}

This would actually be useful. I'm very familiar with the C
preprocessor. I've experimented with the ## operator a lot, and can't
make it do the above task, including experiments related to K+R page
231 about using a second level of macro definition. Can anyone explain
how to solve this problem? Or get the test program to compile and
produce correct array length output?

Thanks,
Daniel Goldman

Jul 29 '07 #1
14 12407
Yes the preprocessor can generate array elemtnes along with complicated
templates:

http://groups.google.com/group/comp....382dc9a40439c7
:^0

Jul 29 '07 #2
dan said:
I would like to have the preprocessor automatically generate the
number of array elements requested. Each element is zero. The elements
get pasted into a larger array. The other elements may be non-zero.
Write, and use, a prepreprocessor . That is, write a program which takes
simple instructions from a file, and which then writes out a .h file
that suits your needs exactly. Then run the program. Then #include the
resulting .h into your code, and you're done.

--
Richard Heathfield <http://www.cpax.org.uk >
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jul 29 '07 #3
dan <da*******@yaho o.comwrites:
I would like to have the preprocessor automatically generate the
number of array elements requested. Each element is zero. The elements
get pasted into a larger array. The other elements may be non-zero.

***** Here is an example of what I need to do:

#define YEAR_1 2005
#define YEAR_2 2007
#define YEARS (YEAR_2 - YEAR_1 + 1)

// Start missing steps (using ## operator in some way?)
// This is the part I can't figure out.

// I think the following definitions are probably needed in the
missing steps
// I'd like ZEROES_AND_COMM AS (YEARS) to get translated to one of them

#define ZEROES_AND_COMM AS_1 0
#define ZEROES_AND_COMM AS_2 0, 0
#define ZEROES_AND_COMM AS_3 0, 0, 0

// End missing steps

#define ARRAY_ELEMS_AGE 0, 1, 5, 10, 15, 20, 40, 60
#define ARRAY_ELEMS_YRS ZEROES_AND_COMM AS (YEARS)
#define ARRAY_ELEMS_EDU 0, 6, 8, 12, 16

int intArray [] = { ARRAY_ELEMS_AGE , ARRAY_ELEMS_YRS ,
ARRAY_ELEMS_EDU , };

// intArray ends up with { 0, 1, 5, 10, 15, 20, 40, 60, 0, 0, 0,
0, 6, 8, 12, 16, }
You don't see averse to C99, going by your comment syntax, so there may
be another way:

int intArray [] = { ARRAY_ELEMS_AGE , [N_AGES+YEARS] = ARRAY_ELEMS_EDU };

You can introduce an index part way into an initialiser list. For
this work, you need to know (as a constant expression) the number of
ARRAY_ELEMS_AGE elements (or, of course, the total size and the number
of training EDU elements).

All elements not explicitly initialised are set to zero (provided
there is at least one value explicit value in the list).

--
Ben.
Jul 29 '07 #4
dan <da*******@yaho o.comwrote:
# I would like to have the preprocessor automatically generate the
# number of array elements requested. Each element is zero. The elements
# get pasted into a larger array. The other elements may be non-zero.

You can probably get (or already have) a real macro processor
like m4 or macros far superior to m4. Use those and most of
your problems will disappear. Depending on your environment
you can have tools like m4, sed, awk, etc and you can write
code the way you want to, and let the software grot it into
something the c compiler can cope with.

For example, it's simple to write a tclsh filter that converts
= to == and := to =. On systems like MacOSX, you can use textutil
to convert programs written as rtfs into plain texts.

#!/usr/bin/tclsh
while {[gets stdin line]>=0} {
puts stdout [string map {:= = = == * != ² <= ³ >= Â !} $line]
}
exit 0

It's odd that for all the advances in user interfaces in the
past forty years, most programmers are still using the tools
and forms of sixties and seventies.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
OOOOOOOOOO! NAVY SEALS!
Jul 29 '07 #5
dan
On Jul 28, 11:38 pm, Richard Heathfield <r...@see.sig.i nvalidwrote:
dan said:
I would like to have the preprocessor automatically generate the
number of array elements requested. Each element is zero. The elements
get pasted into a larger array. The other elements may be non-zero.

Write, and use, a prepreprocessor . That is, write a program which takes
simple instructions from a file, and which then writes out a .h file
that suits your needs exactly. Then run the program. Then #include the
resulting .h into your code, and you're done.

--
Richard Heathfield <http://www.cpax.org.uk >
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
That's a good idea, if I could make it work in this context. USENET is
so helpful for getting suggestions, and of course the poster can never
explain all the context of a complex application. I already use a pre-
pre-processor (shell script with various unix utilities and other
commands) to auto-generate 1) function prototypes header file, and 2)
external definitions header file. It works great.

Related to your suggestion, the pre-pre-processor might either:

- Generate a file for inclusion, with the contents 0, 0, 0

OR

- Edit (using sed) some line like the following:
#define ARRAY_ELEMS_YRS 0, 0, 0

What I don't see is the format for the "simple instructions" where the
pre-pre-processor could understand them. Right now the "simple
instructions" are like the following (embedded within a header file
with about 40,000 lines):

#define YEAR_1 2005
#define YEAR_2 2007
#define YEARS (YEAR_2 - YEAR_1 + 1)

This same code is repeated many times, each time for a different data
scenario. One data set may be 1992-2006. Another may be 2000-2005. So
YEAR_1 and YEAR_2 are defined many times. Based on conditional
compilation, only one of these definitions is compiled.

I don't want to create separate files with "simple
instructions" (instead of using #define YEAR_1 #define YEAR_2). The
overhead would be more maintenance than simply hard-coding
ARRAY_ELEMS_YRS . I just want to make a change in one place (#define
YEAR_2) and everything else is automatically generated.

On further reflection... Perhaps the pre-pre-processor could do the
following:

- cpp -dM the source to generate the #define lines
- grep the conditionally compiled lines for YEAR_1 and YEAR_2
- get the values for YEAR_1 and YEAR_2
- In shell script, use while loop to build "0, 0, 0"
- sed the header file to fix up ARRAY_ELEMS_YRS

Of course, the pre-pre-processor could be invoked in the same shell
script that invokes the regular compile. You can probably tell I was
skeptical the pre-pre-processor would work in this context when I
started writing this post, and am now more optimistic. I'll give it a
try.

Am I correct to assume that you don't think the original idea (somehow
use ## within preprocessor) will work?

Thanks,
Daniel Goldman

Jul 29 '07 #6
dan said:

<snip>
You can probably tell I was
skeptical the pre-pre-processor would work in this context when I
started writing this post, and am now more optimistic. I'll give it a
try.
Glad to hear it. Not suggesting for a moment that it's trivial.
Personally, I think I'd have approached matters rather differently, but
I don't suppose you want to hear that right now, since you're so far
down this road.
Am I correct to assume that you don't think the original idea (somehow
use ## within preprocessor) will work?
I don't see how, really I don't. This kind of trick isn't really what
the pre-processor is for.

--
Richard Heathfield <http://www.cpax.org.uk >
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jul 29 '07 #7
dan
On Jul 29, 10:40 am, SM Ryan <wyrm...@tang o-sierra-oscar-foxtrot-
tango.fake.orgw rote:
dan <dagold...@yaho o.comwrote:

# I would like to have the preprocessor automatically generate the
# number of array elements requested. Each element is zero. The elements
# get pasted into a larger array. The other elements may be non-zero.

You can probably get (or already have) a real macro processor
like m4 or macros far superior to m4. Use those and most of
your problems will disappear. Depending on your environment
you can have tools like m4, sed, awk, etc and you can write
code the way you want to, and let the software grot it into
something the c compiler can cope with.

For example, it's simple to write a tclsh filter that converts
= to == and := to =. On systems like MacOSX, you can use textutil
to convert programs written as rtfs into plain texts.

#!/usr/bin/tclsh
while {[gets stdin line]>=0} {
puts stdout [string map {:= = = == * != <= >= !} $line]}

exit 0

It's odd that for all the advances in user interfaces in the
past forty years, most programmers are still using the tools
and forms of sixties and seventies.

--
SM Ryanhttp://www.rawbw.com/~wyrmwif/
OOOOOOOOOO! NAVY SEALS!
On m4, I looked into that a while back, and decided not. I didn't "get
it". I do use other unix utilities a lot, especially sed and shell
programming.

Can m4 be used in place of cpp for serious development? Is it a good
idea? I couldn't tell from looking at the GNU m4 site or old USENET
posts.

Daniel Goldman

Jul 29 '07 #8
dan
On Jul 28, 11:25 pm, "Chris Thomasson" <cris...@comcas t.netwrote:
Yes the preprocessor can generate array elemtnes along with complicated
templates:

http://groups.google.com/group/comp....browse_frm/thr...

:^0
Concerning the preprocessor generating code via recursion, I looked at
the code and didn't "get it". I'm not saying it doesn't work. Your
suggestion did make me think some more, and I came up with a pretty
simple alternative that seems to work, besides the suggestions from
others (m4, C99 designated array initializaters, pre-pre-processor).
The simple alternative doesn't use recursion or parameterizatio n, but
just tests for each value of YEARS, which is quite manageable. The
example below shows more realistically the actual problem, in terms of
some EDU possibly not being used, so left out of the array. By the
way, the example has three variables, but there can be many tens of
variables, which is why I need to take into account which ones might
be used.

Thanks,
Daniel Goldman

#include <stdio.h>
#include <stdlib.h>

#define YES 1
#define NO 0

#define ISUSED_AGE YES
#define ISUSED_EDU NO

#define YEAR_1 2000
#define YEAR_2 2002
#define YEARS (YEAR_2 - YEAR_1 + 1)

#if ISUSED_AGE == YES
#define ELEMS_AGE 0, 1, 5, 10, 15, 20, 40, 60,
#endif

#if ISUSED_AGE == NO
#define ELEMS_AGE
#endif

#if ISUSED_EDU == YES
#define ELEMS_EDU 0, 6, 8, 12, 16,
#endif

#if ISUSED_EDU == NO
#define ELEMS_EDU
#endif

// assume year var always used

#if YEARS == 1
#define ELEMS_YRS 0,
#endif

#if YEARS == 2
#define ELEMS_YRS 0, 0,
#endif

#if YEARS == 3
#define ELEMS_YRS 0, 0, 0,
#endif

// more of these as needed

main () {
int ndx;
int elems;
int intArray [] = { ELEMS_AGE ELEMS_YRS ELEMS_EDU };

elems = sizeof (intArray) / sizeof (int);
for (ndx = 0; ndx < elems; ndx++) {
printf ("ndx = %d; el = %d\n", ndx, intArray [ndx]);
}
}

Jul 29 '07 #9
dan
On Jul 29, 11:35 am, Richard Heathfield <r...@see.sig.i nvalidwrote:
dan said:

<snip>
You can probably tell I was
skeptical the pre-pre-processor would work in this context when I
started writing this post, and am now more optimistic. I'll give it a
try.

Glad to hear it. Not suggesting for a moment that it's trivial.
Personally, I think I'd have approached matters rather differently, but
I don't suppose you want to hear that right now, since you're so far
down this road.
Am I correct to assume that you don't think the original idea (somehow
use ## within preprocessor) will work?

I don't see how, really I don't. This kind of trick isn't really what
the pre-processor is for.

--
Richard Heathfield <http://www.cpax.org.uk >
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Glad to hear it. Not suggesting for a moment that it's trivial.
Personally, I think I'd have approached matters rather differently, but
I don't suppose you want to hear that right now, since you're so far
down this road.
I don't mind other suggestions. Please let me know what you think.
Even with over 90,000 lines of header files, it's OK to make large-
scale changes because all the coding is done using vi, shell scripts,
sed, etc., and the code is very structured. I write a shell script or
use various vi commands to make big changes quickly.

Maybe you're going to suggest to do the jagged arrays as follows?

int ageIntArray [] = { 0, 5, 10 20, 40, 60};
int eduIntArray [] = { 0, 6, 8, 12, 16 };
int yrsIntArray [] = { 2000, 2001, 2002 };

int *intArrayArray [] = { ageIntArray, eduIntArray, yrsIntArray };

This is how it was previously implemented, with everything getting
filled in with cpp. It worked OK, but there were two problems:

- Had to account in code for whether EDU (or other var) was included
or not. When I needed to alphabetize or otherwise sort an array in
the code, it was "tricky". Now the array just includes the used vars,
so the code is much cleaner.

- Maintaining ageIntArray, eduIntArray, etc. as separate arrays added
a lot of header complexity. Some scenarios have 20 or more variables.
And besides "intArray" various other arrays with other attributes.
Now, instead of 20 separate arrays for intArray, I hoping for one
"jammed" array with all the used elements jammed together, and another
array that is easily set at runtime to point into the jammed array at
the right points.

Thanks,
Daniel

Jul 29 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

205
10469
by: Jeremy Siek | last post by:
CALL FOR PAPERS/PARTICIPATION C++, Boost, and the Future of C++ Libraries Workshop at OOPSLA October 24-28, 2004 Vancouver, British Columbia, Canada http://tinyurl.com/4n5pf Submissions
24
40098
by: Nudge | last post by:
I have an array, and an unrolled loop which looks like this: do_something(A); do_something(A); .... do_something(A); I thought: why should I type so much? I should write a macro. So I was looking to write something along the lines of:
18
3007
by: /* frank */ | last post by:
My teacher said that array in C is managed by preprocessor. Preprocesser replace all array occurences (i.e. int a ) with something that I don't understand/remember well. What's exactly happens with array during preprocessing/compiling stage? Thanks in advance
2
6627
by: Paolo | last post by:
I imported a VC++6.0 project into VC++7.1. The conversion operation makes a mess with Preprocessor Definitions, adding a "$(NoInherit)" for each file. For example: I had a DLL project in VC++6.0 where the definitions were: _UNICODE,_DEBUG,_WIN32_DCOM,WIN32,_WINDOWS,_WINDLL,_AFXDLL,_USRDLL In VC++7.1, these are the preprocessor definitions...
4
2617
by: Klaas Vantournhout | last post by:
Hi, I am currently using OpenMP (gcc 4.2.0) to do parallel computing on a computer with a certain amount of cpu's. I need the total number of cpu's as a variable in my code. So I was wondering how I could do this. Does there exists a system call for that or something or is the best way just to take this out of /proc/cpuinfo? I also...
25
7944
by: Gernot Frisch | last post by:
Hi, I want to build a encryption macro set, that can crypt: char secret = CRYPT("KungFu"); to anything unreadable, and then have a function: char* DECRYPT(char* str) { ...
2
3874
by: =?Utf-8?B?bWFyaw==?= | last post by:
I am contemplating converting a huge collection of functions from C++ to VB.NET. I am concerned with a style used in the original code where a variable is set to a constant value with the # define preprocessor symbol. For example: void Mysub (...){ # define indx 2 double x = {2.3, 3.4}; blah blah; # undef indx
31
2887
by: Sam of California | last post by:
Is it accurate to say that "the preprocessor is just a pass in the parsing of the source file"? I responded to that comment by saying that the preprocessor is not just a pass. It processes statements that the compiler does not process. The good people in the alt.comp.lang.learn.c-c++ newsgroup insist that the preprocessor is just one of...
1
2751
by: Peter Ammon | last post by:
I was watching a video about a new C front end for the LLVM C compiler (on youtube, of all places), and the author made an interesting claim: that writing a C preprocessor is much harder, and requires more code, than a C parser. Is this true? And if so, why? Thanks! -Peter
0
7655
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, well explore What is ONU, What Is Router, ONU & Routers main...
0
7577
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7869
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. ...
0
8101
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...
1
7627
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
3623
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...
1
2073
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
1
1191
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
903
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...

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.