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

Howto do the impossible with #define ?>?

P: n/a
It sure would be nice if I could have a macro that add a level of
indirection to its argument.

So if I write: AddIndirection( X )

The macro AddIndirection will do: #define X (*X)

so after that point whenever you use X it gets replaced by (*X)
Now I KNOW you can't have a #define generate another #define, but is
there some sneaky way to do this? Surely the cpp gurus out there can
figure out how?

Thanks,

grg

Jul 6 '06 #1
Share this Question
Share on Google+
29 Replies


P: n/a
Ancient_Hacker wrote:
It sure would be nice if I could have a macro that add a level of
indirection to its argument.

So if I write: AddIndirection( X )

The macro AddIndirection will do: #define X (*X)

so after that point whenever you use X it gets replaced by (*X)
The reason you think this would be "nice" escapes me.
What sort of use would you intend for this bletcherous idea?
Now I KNOW you can't have a #define generate another #define, but is
there some sneaky way to do this? Surely the cpp gurus out there can
figure out how?
Yes, you can do it. But you'll need to spell the
directive a little differently: instead of

AddIndirection(X)

you must write

#define X (*X)

.... and I suspect you will quickly come to regret writing it.

--
Eric Sosman
es*****@acm-dot-org.invalid
Jul 6 '06 #2

P: n/a

Eric Sosman wrote:

The reason you think this would be "nice" escapes me.
What sort of use would you intend for this bletcherous idea?

Did I ask for an opinion as to the nicety of this?

As to the blecherosity of this, it actually has a valid use.

Let's say you're writing a dynamic array library ( for C ). You'd like
the user to be able to write:

MakeMeAnArrayWithFourDimensions( float, MyArray, 10, 20, 30, 40 )

No, you need not comment on my choice of macro names.

One can implement this with:

#define(t,n,d1,d2,d3,d4) \
typedef t n##_Type [d1][d2][d3][d4]; \
typedef n##_Type * n##_Type_Ptr; \
static n##_Type_Ptr n; \
n = (n##_Type_Ptr) malloc( sizeof( n##_Type ) );
No, I don't need your comments about my superflous type definitions and
how clever you could squeeze this down to one line.
Now the only problem is this array MyArray is actually a pointer to
MyArray, so the poor user will have to write (*A) [i][j][k][q], which
is annoying. Or we could supply yet another macro : #define
Access(n,i,j,k,q) (*n)[i][j][k][q] but that also is less than
optimum. or we could have created a function: t n(int d1, int d2, int
d3, int d4) {
return * N##_Var[d1][d2][d3][d4] } .... except we'd need a separate
one for returning lvalues.

The only way I can see how to make the use as transparent as possible
is to do a #define MyArray(*MyArray). For those of you that think
this is recursive, it's not, cpp handles this case just fine.
I solicit any clever ideas as to how to do this or similar.

Thanks,

grg
Yes, you can do it. But you'll need to spell the
directive a little differently: instead of

AddIndirection(X)

you must write

#define X (*X)

... and I suspect you will quickly come to regret writing it.

I wonder why you mention this. My original posting clearly indicates
my wish to do this automatically. You somehow feel compelled to beg
the question, plus show an unerring ability to read my mind in the
future. Surely someone of your Godlike powers has better things to do
than quibble on usenet newsgroups?

Jul 7 '06 #3

P: n/a
Ancient_Hacker wrote:
Eric Sosman wrote:
> The reason you think this would be "nice" escapes me.
What sort of use would you intend for this bletcherous idea?

Did I ask for an opinion as to the nicety of this?
No, you did not ask. You merely stated that "It sure
would be nice," offering no reason why anyone would think
so. I questioned -- and continue to question -- what you
apparently take as an axiom.
As to the blecherosity of this, it actually has a valid use.

Let's say you're writing a dynamic array library ( for C ). You'd like
the user to be able to write:

MakeMeAnArrayWithFourDimensions( float, MyArray, 10, 20, 30, 40 )

No, you need not comment on my choice of macro names.

One can implement this with:

#define(t,n,d1,d2,d3,d4) \
typedef t n##_Type [d1][d2][d3][d4]; \
typedef n##_Type * n##_Type_Ptr; \
static n##_Type_Ptr n; \
n = (n##_Type_Ptr) malloc( sizeof( n##_Type ) );
No, I don't need your comments about my superflous type definitions and
how clever you could squeeze this down to one line.
Now the only problem is this array MyArray is actually a pointer to
MyArray, so the poor user will have to write (*A) [i][j][k][q], which
is annoying. Or we could supply yet another macro : #define
Access(n,i,j,k,q) (*n)[i][j][k][q] but that also is less than
optimum. or we could have created a function: t n(int d1, int d2, int
d3, int d4) {
return * N##_Var[d1][d2][d3][d4] } .... except we'd need a separate
one for returning lvalues.

The only way I can see how to make the use as transparent as possible
is to do a #define MyArray(*MyArray). For those of you that think
this is recursive, it's not, cpp handles this case just fine.
Second point first: Of course it isn't recursive; that's the
way the C language is defined.

As for the larger issue, your problem is caused by the wrong
choice of pointer type. Use a pointer to a 3D array to access
your 4D array, and all the problems will disappear. Keep in mind
that C really doesn't have multi-dimensional arrays: it has one-
dimensional arrays whose elements can be one-dimensional arrays,
whose elements can in turn be one-dimensional arrays, ...

When you want to allocate a one-dimensional array of `char',
say, what pointer type do you use? A "zero-dimensional" `char*',
not a one-dimensional `(char[N])*', right? You don't want a pointer
to the array, you want a pointer to the array element -- hence, you
want a pointer with "one less dimension" than the overall array.
I solicit any clever ideas as to how to do this or similar.
If by "this" you mean cause an automatic redefinition, I think
you are out of luck. If by "this" you mean you want to solve the
problem, there's nothing especially "clever" about the straightforward
solution outlined above, but it will work lots better.
>>you must write

#define X (*X)

... and I suspect you will quickly come to regret writing it.

I wonder why you mention this. My original posting clearly indicates
my wish to do this automatically. You somehow feel compelled to beg
the question, plus show an unerring ability to read my mind in the
future. Surely someone of your Godlike powers has better things to do
than quibble on usenet newsgroups?
I mention my suspicion to counter your unsupported assertion
that "It sure would be nice." I remain suspicious.

--
Eric Sosman
es*****@acm-dot-org.invalid
Jul 7 '06 #4

P: n/a
In article <11*********************@s16g2000cws.googlegroups. com>,
Ancient_Hacker <gr**@comcast.netwrote:
....
>I wonder why you mention this. My original posting clearly indicates
my wish to do this automatically. You somehow feel compelled to beg
the question, plus show an unerring ability to read my mind in the
future. Surely someone of your Godlike powers has better things to do
than quibble on usenet newsgroups?
Unfortunately, not. That's what's so funny about this group.
You've got all these allegedly high-power, experts-in-their-fields, in
fact, gosh and golly, some of 'em have even claimed to have written (and
gotten published!) actual real live books, yet they don't seem to have
anything better to do with their time than nit-pick strangers here.

Useful clc-related links:

http://en.wikipedia.org/wiki/Clique
http://en.wikipedia.org/wiki/Aspergers
http://en.wikipedia.org/wiki/C_programming_language

Jul 7 '06 #5

P: n/a

Eric Sosman wrote:
As for the larger issue, your problem is caused by the wrong
choice of pointer type. Use a pointer to a 3D array to access
your 4D array, and all the problems will disappear.
I should have mentioned, this is in an extremely time_critical app
which already runs for upwards of a week sometimes. We can't afford
the overhead of chasing several pointers
just to get to a data value.

Keep in mind that C really doesn't have multi-dimensional arrays:
It's hard to keep this in mind, especially since IT IS NOT TRUE.

You can declare, in 1973 K&R C: float X[10][20][30]; /* Not A
problem */

What you can't do, at any time between then and now, is pass various
multi-dim arrays as a parameter and expect the receiving function to
index into them correctly. This is something FORTRAN has had since
1959.
it has one-
dimensional arrays whose elements can be one-dimensional arrays,
whose elements can in turn be one-dimensional arrays, ...
yes, many of us are familiar with that kludgy way of faking
"multi-dimensinal arrays". Not interested in paying the price.
Regards,
grg

Jul 7 '06 #6

P: n/a
Eric Sosman said:

<snip>
Keep in mind that C really doesn't have multi-dimensional arrays:
I must take issue with you there. C /does/ have multi-dimensional arrays,
because the Standard says it does. 3.3.2.1 and 3.5.7 have plenty of
references to them. (In C99, see 6.5.2.1.)

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jul 7 '06 #7

P: n/a
Ancient_Hacker wrote:
Eric Sosman wrote:
> As for the larger issue, your problem is caused by the wrong
choice of pointer type. Use a pointer to a 3D array to access
your 4D array, and all the problems will disappear.

I should have mentioned, this is in an extremely time_critical app
which already runs for upwards of a week sometimes. We can't afford
the overhead of chasing several pointers
just to get to a data value.
"Chasing several pointers ...?" Oh: You've mis-read
what was written.
>Keep in mind that C really doesn't have multi-dimensional arrays:

It's hard to keep this in mind, especially since IT IS NOT TRUE.
... and the Moon REALLY IS made of green cheese.
You can declare, in 1973 K&R C: float X[10][20][30]; /* Not A
problem */
No, it's not a problem. X is an array of ten things.
each of those -- X[1], for instance -- is an array of twenty
things. Each of those -- e.g. X[1][3] -- is an array of
thirty floats.
What you can't do, at any time between then and now, is pass various
multi-dim arrays as a parameter and expect the receiving function to
index into them correctly. This is something FORTRAN has had since
1959.
"Multi-dimensional" arrays work just fine as parameters,
as long as all but the first dimension are known and constant.
C99 removes the "and constant" part.

As for FORTRAN -- well, if you prefer it, why not use it?
C is certainly not the only language around; it's just the only
one that's topical on this newsgroup.
>>it has one-
dimensional arrays whose elements can be one-dimensional arrays,
whose elements can in turn be one-dimensional arrays, ...

yes, many of us are familiar with that kludgy way of faking
"multi-dimensinal arrays". Not interested in paying the price.
You didn't read carefully.

--
Eric Sosman
es*****@acm-dot-org.invalid

Jul 7 '06 #8

P: n/a
Richard Heathfield posted:
Eric Sosman said:

<snip>
>Keep in mind that C really doesn't have multi-dimensional arrays:

I must take issue with you there. C /does/ have multi-dimensional arrays,
because the Standard says it does. 3.3.2.1 and 3.5.7 have plenty of
references to them. (In C99, see 6.5.2.1.)

I agree, C certainly does have multi-dimensional arrays.
int (*p_array)[2][4][8][16] =
malloc( sizeof(int) * 2 * 4 * 8 * 16 );

(*p_array)[1][3][7][15] = -78;
p_array[0][1][3][7][15] = -78;

--

Frederick Gotham
Jul 7 '06 #9

P: n/a
Ancient_Hacker said:

<snip>
>
I should have mentioned, this is in an extremely time_critical app
which already runs for upwards of a week sometimes. We can't afford
the overhead of chasing several pointers
just to get to a data value.
If that's your bottleneck, you're very fortunate. At the risk of being
attacked simply for attempting to help you, I would add that I think your
time would be better spent looking at your algorithm choices, rather than
trying to find a crufty way to hack the preprocessor.

<snip>
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jul 7 '06 #10

P: n/a
Frederick Gotham said:
Richard Heathfield posted:
>Eric Sosman said:

<snip>
>>Keep in mind that C really doesn't have multi-dimensional arrays:

I must take issue with you there. C /does/ have multi-dimensional arrays,
because the Standard says it does. 3.3.2.1 and 3.5.7 have plenty of
references to them. (In C99, see 6.5.2.1.)


I agree, C certainly does have multi-dimensional arrays.
int (*p_array)[2][4][8][16] =
malloc( sizeof(int) * 2 * 4 * 8 * 16 );
More simply:

int (*p_array)[2][4][8][16] = malloc(sizeof *p_array);

if(p_array != NULL)
{
/* THEN you can do this... */
(*p_array)[1][3][7][15] = -78;
p_array[0][1][3][7][15] = -78;
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jul 7 '06 #11

P: n/a
Richard Heathfield wrote:
Eric Sosman said:

<snip>
>>Keep in mind that C really doesn't have multi-dimensional arrays:


I must take issue with you there. C /does/ have multi-dimensional arrays,
because the Standard says it does. 3.3.2.1 and 3.5.7 have plenty of
references to them. (In C99, see 6.5.2.1.)
Well, since the Standard uses the term I guess I have to
concede it. IMHO, though, it's a notional convenience that has
snuck into the normative text, sort of like "address" (an idea
C doesn't really need at all).

Note that the description of subscripting in 6.5.2.1/3 is
only one-dimensional; the operation on a "multi-dimensional"
array is described in terms of the decomposition of the MDA
into a singly-dimensioned array of singly-dimensioned arrays
of singly-dimensioned arrays of ... There is a [] operator,
but no [][] operator.

Also, note that the language grammar has no syntax for
declaring an array with multiple dimensions. Rather, it has
syntax for declaring arrays of arrays.

Still, if the Standard says so ... All right, I yield.

--
Eric Sosman
es*****@acm-dot-org.invalid
Jul 7 '06 #12

P: n/a
Eric Sosman said:
Richard Heathfield wrote:
>Eric Sosman said:
>>>Keep in mind that C really doesn't have multi-dimensional arrays:

I must take issue with you there. C /does/ have multi-dimensional arrays,
because the Standard says it does. 3.3.2.1 and 3.5.7 have plenty of
references to them. (In C99, see 6.5.2.1.)

Well, since the Standard uses the term I guess I have to
concede it. IMHO, though,
[Objections 1 through 4 - snipped]

Still, if the Standard says so ... All right, I yield.
Your objections are very sensible, but you are right to yield. Let us never
forget that sensible != normative. :-)

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jul 7 '06 #13

P: n/a
Frederick Gotham wrote:
Richard Heathfield posted:

>>Eric Sosman said:

<snip>
>>>Keep in mind that C really doesn't have multi-dimensional arrays:

I must take issue with you there. C /does/ have multi-dimensional arrays,
because the Standard says it does. 3.3.2.1 and 3.5.7 have plenty of
references to them. (In C99, see 6.5.2.1.)

I agree, C certainly does have multi-dimensional arrays.
int (*p_array)[2][4][8][16] =
malloc( sizeof(int) * 2 * 4 * 8 * 16 );

(*p_array)[1][3][7][15] = -78;
p_array[0][1][3][7][15] = -78;
.... and my suggestion to the O.P. is that he lose the useless
first dimension in the pointer type:

int (*p_array)[4][8][16] =
malloc(sizeof(int) * 2 * 4 * 8 * 16);
/* better: malloc(2 * sizeof *p_array) */
p_array[1][3][7][15] = -78;

--
Eric Sosman
es*****@acm-dot-org.invalid
Jul 7 '06 #14

P: n/a

Eric Sosman wrote:
"Chasing several pointers ...?" Oh: You've mis-read
what was written.
No I havent. It appears you have a very weak idea of what actually has
to happen when you declare an array of array of array of pointers.
Here's a clue:
when you write: x = Array[i][j][k][q];

AND Array has been declared as the usual kludge, as **** pointers,
the compiler has NO CHOICE but to load up each array index variable,
use it as an index into the array, fetrch the pointer to the next
higher dimension, and repeat that as many times as necessary,.
There's example code from the microsoft C compiler for doing just this:
; 27 : Tot += a_slow_array[i][j][k];

000c5 8b 45 fc mov eax, DWORD PTR _i$[ebp]
000c8 8b 4d f0 mov ecx, DWORD PTR _a_slow_array$[ebp]
000cb 8b 14 81 mov edx, DWORD PTR [ecx+eax*4]
000ce 8b 45 ec mov eax, DWORD PTR _j$[ebp]
000d1 8b 0c 82 mov ecx, DWORD PTR [edx+eax*4]
000d4 db 45 f8 fild DWORD PTR _Tot$[ebp]
000d7 8b 55 f4 mov edx, DWORD PTR _k$[ebp]
000da d8 04 91 fadd DWORD PTR [ecx+edx*4]
000dd e8 00 00 00 00 call __ftol2_sse
000e2 89 45 f8 mov DWORD PTR _Tot$[ebp], eax
000e5 eb cf jmp SHORT $LN2@wmain
$LN1@wmain:
000e7 eb b5 jmp SHORT $LN5@wmain
$LN4@wmain:
000e9 eb 9b jmp SHORT $LN8@wmain
$LN7@wmain:

You see no optimization is possible, as the compiler has to assume any
value in the pointer array may change at any time. So it has to
generate the really slow code to load up all those pointers. And the
instructions can't be overlapped, as each instruction depends on teh
result of the previous one.

----

But if instead the array is expicitly declared, all the overhead goes
away.
And the compiler can clearly see what index variables are invariant in
the inner loops, so those array subscripts need not be recalculated
each time. And there are fewer temporary registers used, so the code
can be ioptimized even more.. The code is much shorter and faster:

0015b db 45 f8 fild DWORD PTR _Tot$[ebp]
0015e 8b 45 f4 mov eax, DWORD PTR _k$[ebp]
00161 d8 44 81 fc fadd DWORD PTR [ecx+eax*4-4]
>
Keep in mind that C really doesn't have multi-dimensional arrays:
It's hard to keep this in mind, especially since IT IS NOT TRUE.

... and the Moon REALLY IS made of green cheese.
Are you still in denial?
What you can't do, at any time between then and now, is pass various
multi-dim arrays as a parameter and expect the receiving function to
index into them correctly. This is something FORTRAN has had since
1959.

"Multi-dimensional" arrays work just fine as parameters,
as long as all but the first dimension are known and constant.
C99 removes the "and constant" part.
Read the sentence: Various multi-dimensional arrays. You can't pass:
float X[10][20]
and
float Y[20][30]

to the same routine (say, MatMul). C has no way of conveying the
dimension information, so the called routine has no idea what the
caling array's dimensions are.
yes, many of us are familiar with that kludgy way of faking
"multi-dimensinal arrays". Not interested in paying the price.

You didn't read carefully.
You don't think carefully.

Jul 7 '06 #15

P: n/a

Richard Heathfield wrote:
If that's your bottleneck, you're very fortunate. At the risk of being
attacked simply for attempting to help you, I would add that I think your
time would be better spent looking at your algorithm choices,
That's usually a swell idea, but the code in question is about 45,000
lines long, already uses lots of optimized matrix libraries, been pored
over by experts for over a decade now.

What would really help is getting these arrays transparently modded
into the code.

Jul 7 '06 #16

P: n/a
Ancient_Hacker writes:
Eric Sosman wrote:
> "Chasing several pointers ...?" Oh: You've mis-read
what was written.
No I havent. It appears you have a very weak idea of what actually
has to happen when you declare an array of array of array of pointers.
Which neither of you have suggested.
Here's a clue:
when you write: x = Array[i][j][k][q];

AND Array has been declared as the usual kludge, as **** pointers,
Which neither of you have suggested either.
And it is different from an "array of array of array of pointers".
There's example code from the microsoft C compiler for doing just
this:
Indeed. Now have a look at assembly code produced from the code
Eric suggested, instead of the code he didn't suggest.
> "Multi-dimensional" arrays work just fine as parameters,
as long as all but the first dimension are known and constant.
C99 removes the "and constant" part.

Read the sentence: Various multi-dimensional arrays. You can't pass:
float X[10][20]
and
float Y[20][30]
Ah, you didn't say that's what you meant until just recently.
You said you wanted macros. I'm as confused as Eric about why
you think those will make a difference. But let's see -

As you yourself say,
"What you can't do, at any time between then and now, is pass various
multi-dim arrays as a parameter and expect the receiving function to
index into them correctly. This is something FORTRAN has had since
1959."
Correct until C99. And any macros you could add would not make a
difference. You'd have to define a one-dimentional arrays and implement
a multi-dim array "by hand" in the function which used it, or something.
(You could use macros to make that easier of course.)

You can pass variable-length arrays to C99 functions, but you need to
tell the function the array lengths as well. E.g.

int foo(int j, int k, int a[*][j][k])
{
return a[1][2][3];
}

which doesn't work in gcc yet, but you could pass a pointer to the
multi-dim array instead or use

int foo(int i, int j, int k, int a[i][j][k])
{
return a[1][2][3];
}

Also, in C++ you could have declared a function using templates.

--
Hallvard
Jul 7 '06 #17

P: n/a
Ancient_Hacker wrote:
Eric Sosman wrote:

> "Chasing several pointers ...?" Oh: You've mis-read
what was written.


No I havent.
"Yes, you have."
It appears you have a very weak idea of what actually has
to happen when you declare an array of array of array of pointers.
You are the introducer of the "array of pointers" idea,
not I. If you will go back and read what I wrote, you will
see that I spoke of a pointer, singular, and of an array of
arrays of arrays of floats. There was no mention, none, zero,
nada, zip, nil, of any array of pointers anywhere in what I
wrote.
Here's a clue:

when you write: x = Array[i][j][k][q];

AND Array has been declared as the usual kludge, as **** pointers,
It would be clearer to exhibit an actual declaration.
I do not know what you mean by "**** pointers." (I can guess,
but you have left too much room for guesswork and I do not
wish to waste time discussing strawmen. Either write exactly
what you mean, or drop the subject.)
the compiler has NO CHOICE but to load up each array index variable,
use it as an index into the array, fetrch the pointer to the next
higher dimension, and repeat that as many times as necessary,
You are describing an entirely different data structure
from the one I suggested lo! these many flames ago.
>>>>Keep in mind that C really doesn't have multi-dimensional arrays:

It's hard to keep this in mind, especially since IT IS NOT TRUE.

... and the Moon REALLY IS made of green cheese.

Are you still in denial?
No; Richard Heathfield has pointed out my error. You
will note, though, that array subscripting is defined as
one-dimensional, consistent with the "arrays of arrays"
model. "Multi-dimensional array" is officially sanctioned
nomenclature, but carries no meaning beyond "array of arrays."
A multi-dimensional array behaves exactly as I described.
>>>yes, many of us are familiar with that kludgy way of faking
"multi-dimensinal arrays". Not interested in paying the price.

You didn't read carefully.

You don't think carefully.
No; I am careless, especially when someone who asks for
help and recieves it responds like North Korea on a bad hair
day.

--
Eric Sosman
es*****@acm-dot-org.invalid

Jul 7 '06 #18

P: n/a
Eric Sosman <es*****@acm-dot-org.invalidwrites:
Richard Heathfield wrote:
>Eric Sosman said:
<snip>
>>>Keep in mind that C really doesn't have multi-dimensional arrays:
I must take issue with you there. C /does/ have multi-dimensional
arrays, because the Standard says it does. 3.3.2.1 and 3.5.7 have
plenty of references to them. (In C99, see 6.5.2.1.)

Well, since the Standard uses the term I guess I have to
concede it. IMHO, though, it's a notional convenience that has
snuck into the normative text, sort of like "address" (an idea
C doesn't really need at all).

Note that the description of subscripting in 6.5.2.1/3 is
only one-dimensional; the operation on a "multi-dimensional"
array is described in terms of the decomposition of the MDA
into a singly-dimensioned array of singly-dimensioned arrays
of singly-dimensioned arrays of ... There is a [] operator,
but no [][] operator.

Also, note that the language grammar has no syntax for
declaring an array with multiple dimensions. Rather, it has
syntax for declaring arrays of arrays.

Still, if the Standard says so ... All right, I yield.
Some languages have multidimensional arrays as a built-in feature,
distinct from arrays of arrays. C doesn't. It only has arrays,
arrays of arrays, and so forth -- but it uses the term
"multidimensional arrays" to refer to them.

As far as I can tell, C99 6.5.2.1p3, which describes multidimensional
array indexing, is redundant. The rules for indexing into a
multidimensional array follow directly from the rules for indexing
into a one-dimensional array. If that paragraph were removed from the
standard, it wouldn't change the language, except that Eric's
statement that C doesn't have multidimensional arrays, but only arrays
of arrays, would be correct. It's just a matter of terminology.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jul 7 '06 #19

P: n/a

Sorry folks,, I thought we were talking about the very common (if you
Google for "C multi-dimensional dynamic arrays") trick of malloc()ing
an array of pointers to each row, then mallocing an array of pointers
to each of those arrays. Works, but that's about all.

Glad to hear C99 is up to FORTRAN59 level of array handling.

Jul 7 '06 #20

P: n/a
"Ancient_Hacker" <gr**@comcast.netwrites:
Sorry folks,, I thought we were talking about the very common (if you
Google for "C multi-dimensional dynamic arrays") trick of malloc()ing
an array of pointers to each row, then mallocing an array of pointers
to each of those arrays. Works, but that's about all.

Glad to hear C99 is up to FORTRAN59 level of array handling.
Until recently, Google by default didn't provide context for
followups. They've fixed this bug. Please take advantage of it by
leaving enough context in your followup so it makes sense by itself.
We can't necessarily easily see or remember the previous article.

For those who haven't read it, section 6 of the comp.lang.c FAQ,
<http://www.c-faq.com/>, provides a lot of good information in this
area.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jul 7 '06 #21

P: n/a

Eric Sosman wrote:
I think it's wonderful there are a few language-lawyers out there. We
need them to argue about the fine points of a language, such as how
many sequence points can fit on the head of a pin. Or why there's a
stringify escape character, but no char-ify escape. Many years ago
one of my friends was on a standards comittee, and he spent years
flying to monthly meetings where they endlessly discussed such things,
until finally the language in question just expired due to lack of a
standard.

All in the good old tradition, going back to Aristotle, where a bunch
of smart guys in togas would gather on a hilltop and grope each other
under the table while arguing eloquently and forecefully what the right
number of teeth were for a horse. One would argue that 24 was the
right number, as that's the number of vestal virgins on the Agean
corniche. Others would just as forcefully argue that 28 is the number,
as 2 plus eight is ten, the number of fingers Jove gave to Man.

But the other 99.5% of us are interested in more prosaic things, like
how to get our beleepin job done with this IMHO just about the most
cranky and train-wrecky of languages.

Now I'm not complaining TOO much, but when a guy asks for the answer to
how to remove the lug-nuts on a 66 Dodge Charger, he isnt helped much
by being given vague hints and insults as to how he's a moron cause he
doesnt know how the steel for the lug-wrench was forged. Much more
useful to gently remind him the lug-nuts on the right side are
left-hand thread.

When a guy asks how to put out the fire on his head, it doesnt help to
discourse on the quantum-principles that give H2O a high heat of
vaporization. Much better to suggest dunking his head in some nearby
lake. Which I sometimes need even when not on fire.

If you look back, there are 20+ replies to my question, not a single
one of them a clear or complete solution. A couple of good hints,
using which I was able to figure out that yes, for some unfathomable
reason, if you declare a 3-d array and index it with FOUR subscripts,
voila, the right indexing code gets generated. But also an awful lot
of self-preening comments and probably intentional ingenuousness.

I admit I participated in some misunderstanding as to the exact method
being suggested. I also should have explained exactly what I was
wanting to do, not asked for one dubious way of finishing up my
solution.

but still without clear concise and full and to the point examples,
confusion and digressions just blossom.

So not to overstate the obvious, when somebody asks a simple, basic
question, wouldnt it be nice to just reply with an answer, rather than
to stroke one's own ego by showing off how erudite one is in citing
chapter, verse, sentence, word, and syllable of something totally
unhelpful to the direct object of discourse?

Jul 8 '06 #22

P: n/a
In article <11*********************@s53g2000cws.googlegroups. com>,
Ancient_Hacker <gr**@comcast.netwrote:
>So not to overstate the obvious, when somebody asks a simple, basic
question, wouldnt it be nice to just reply with an answer ...
OK: the answer is, it is quite literally impossible to do what you
asked for.

You seem to hate the idea that someone might quote parts of the
standards to you, but here is the part that, in effect, says "you
cannot have a #define create a new #define":

[#1] After all parameters in the replacement list have been
substituted and # and ## processing has taken place, all
placemarker preprocessing tokens are removed, then the
resulting preprocessing token sequence is rescanned with all
subsequent preprocessing tokens of the source file for more
macro names to replace.

[#2] If the name of the macro being replaced is found during
this scan of the replacement list (not including the rest of
the source file's preprocessing tokens), it is not replaced.
Further, if any nested replacements encounter the name of
the macro being replaced, it is not replaced. These
nonreplaced macro name preprocessing tokens are no longer
available for further replacement even if they are later
(re)examined in contexts in which that macro name
preprocessing token would otherwise have been replaced.

[#3] The resulting completely macro-replaced preprocessing
token sequence is not processed as a preprocessing directive
*even if it resembles one* ... [emphasis mine]

That last clause means that no matter how you trick a C compiler
into taking:

#define THIS(x) \
<whatever replacement text you like, including a "#" and "define">

so that the result includes the sequence:

#define THAT(x) (*x)

this resulting "#define" will not be acted-upon.

You have to give up on this approach. There are others, though.
Re-read Eric Sosman's replies, and you will find a simpler method
that works just fine for what you *really* wanted to do. Or, if
you want to write unnecessary code (instead of using the simpler
method he suggested), write your own "pre-preprocessor" and run
your code through that before running it through a C compiler.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Jul 10 '06 #23

P: n/a
On 8 Jul 2006 06:22:44 -0700, "Ancient_Hacker" <gr**@comcast.net>
wrote:
>
Eric Sosman wrote:
Bravo. Excellent post.
>I think it's wonderful there are a few language-lawyers out there. We
need them to argue about the fine points of a language, such as how
many sequence points can fit on the head of a pin. Or why there's a
stringify escape character, but no char-ify escape. Many years ago
one of my friends was on a standards comittee, and he spent years
flying to monthly meetings where they endlessly discussed such things,
until finally the language in question just expired due to lack of a
standard.
And you could say almost the same thing if your friend was on the C99
standards comittee:

"Many years ago one of my friends was on a standards comittee, and he
spent years flying to monthly meetings where they endlessly discussed
such things, until finally the language in question just expired us
due to lack of a standard agreement. And thus C99 was born."

[snip]
>Now I'm not complaining TOO much, but when a guy asks for the answer to
how to remove the lug-nuts on a 66 Dodge Charger, he isnt helped much
by being given vague hints and insults as to how he's a moron cause he
doesnt know how the steel for the lug-wrench was forged.
Even someone who knows how to "steal the lug-wrench" knows how to
remove the lug-nuts on a 66 Dodge Charger. That's more progressive
than most morons. Sad but (NULL == 0) (the latter expression evaluates
to "true", for you morons :^)).
>When a guy asks how to put out the fire on his head, it doesnt help to
discourse on the quantum-principles that give H2O a high heat of
vaporization. Much better to suggest dunking his head in some nearby
lake. Which I sometimes need even when not on fire.
Pointed pursuasiveness followed up by an expression of humbleness.
Brilliant.
If you look back, there are 20+ replies to my question, not a single
one of them a clear or complete solution. A couple of good hints,
using which I was able to figure out that yes, for some unfathomable
reason, if you declare a 3-d array and index it with FOUR subscripts,
voila, the right indexing code gets generated. But also an awful lot
of self-preening comments and probably intentional ingenuousness.

I admit I participated in some misunderstanding as to the exact method
being suggested. I also should have explained exactly what I was
wanting to do, not asked for one dubious way of finishing up my
solution.

but still without clear concise and full and to the point examples,
confusion and digressions just blossom.

So not to overstate the obvious, when somebody asks a simple, basic
question, wouldnt it be nice to just reply with an answer, rather than
to stroke one's own ego by showing off how erudite one is in citing
chapter, verse, sentence, word, and syllable of something totally
unhelpful to the direct object of discourse?
Yes.

All we need now for this thread to end is for Chris Torek to respond
to your post with a smack of reality that Every Good Boy who Does Fine
should read.

Take care
--
jay
Jul 10 '06 #24

P: n/a


Richard Heathfield wrote On 07/07/06 11:35,:
Eric Sosman said:
>>Richard Heathfield wrote:
>>>Eric Sosman said:

Keep in mind that C really doesn't have multi-dimensional arrays:

I must take issue with you there. C /does/ have multi-dimensional arrays,
because the Standard says it does. 3.3.2.1 and 3.5.7 have plenty of
references to them. (In C99, see 6.5.2.1.)

Well, since the Standard uses the term I guess I have to
concede it. IMHO, though,

>>[Objections 1 through 4 - snipped]

Still, if the Standard says so ... All right, I yield.


Your objections are very sensible, but you are right to yield. Let us never
forget that sensible != normative. :-)
Hah! I *knew* I wasn't just dreaming when I said C
didn't have multi-dimensional arrays. One authoritative
source uses the term "multi-dimensional array," but says

"In C, by definition a two-dimensional array is
really a one-dimensional array, each of whose
elements is an array."
-- Brian W. Kernighan and Dennis M. Ritchie,
"The C Programming Language," p. 104

However, even K&R, though authoritative, are non-normative.

--
Er*********@sun.com

--
Er*********@sun.com

Jul 10 '06 #25

P: n/a
Okay, so it's not doable. But here's two ways to do it:
cpp %Fn% | cc %CCOpts% # pre-process the file *twice*
perl -e "s/%ENV{'AList'}/\(\*\1\)/g" %Fn% | cc
.... and of course the adumbrated way of defining a 3D array and using 4
subscripts. Stimulates one's gag reflex the first 77 times you use it,
but hey, it's C.

Jul 10 '06 #26

P: n/a

Ancient_Hacker wrote:
Okay, so it's not doable. But here's two ways to do it:
cpp %Fn% | cc %CCOpts% # pre-process the file *twice*
perl -e "s/%ENV{'AList'}/\(\*\1\)/g" %Fn% | cc
... and of course the adumbrated way of defining a 3D array and using 4
subscripts. Stimulates one's gag reflex the first 77 times you use it,
but hey, it's C.

READY
cpp %Fn% | cc %CCOpts% # pre-process the file *twice*
cpp: line 0, Error: Too many file arguments. Usage: cpp :input
:output::

READY
perl -e "s/%ENV{'AList'}/\(\*\1\)/g" %Fn% | cc
IKJ56500I COMMAND PERL NOT FOUND
READY

Doesn't work.

Jul 10 '06 #27

P: n/a
IKJ56500I COMMAND PERL NOT FOUND
Jeeepers, what OS is *that*? Univac 1100 OS? Chippewa? George IV?
Multics? :)

Jul 10 '06 #28

P: n/a

Ancient_Hacker wrote:
IKJ56500I COMMAND PERL NOT FOUND

Jeeepers, what OS is *that*? Univac 1100 OS? Chippewa? George IV?
Multics? :)
http://www-03.ibm.com/servers/eserver/zseries/zos/

Jul 10 '06 #29

P: n/a
"Ancient_Hacker" <gr**@comcast.netwrites:
> IKJ56500I COMMAND PERL NOT FOUND

Jeeepers, what OS is *that*? Univac 1100 OS? Chippewa? George IV?
Multics? :)
A quick Google says z/OS, aka MVS, aka OS/390, aka other things too.
--
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
Jul 10 '06 #30

This discussion thread is closed

Replies have been disabled for this discussion.