473,386 Members | 1,715 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

problem with macros

Hello, I have the following structure -

typedef struct
{
double x, y, z;

}vector;

In certain places, I could avoid triplification of code by using an
array instead of x, y, z. For eg:

typedef struct
{
double coord[3];

} vector;

But this notation does not some people who are going to read my code
(physics people). They are used to x, y, z notation for vectors. Also
I use long expressions in some places and using coord[index] makes it
even more intricate. So I decided to use x, y, z notation but I wrote
some macros that could help me in reducing the triplification of code
that may happen at some places:

#define coord[0] x
#define coord[1] y
#define coord[2] z

I thought this will allow array indexing of the coordinates but
instead I got an error "coord redefined" . Why is that ?
Aug 1 '08 #1
80 2834
On 1 Aug 2008 at 20:52, pereges wrote:
Hello, I have the following structure -

typedef struct
{
double x, y, z;

}vector;

In certain places, I could avoid triplification of code by using an
array instead of x, y, z. For eg:

typedef struct
{
double coord[3];

} vector;

But this notation does not some people who are going to read my code
(physics people). They are used to x, y, z notation for vectors. Also
I use long expressions in some places and using coord[index] makes it
even more intricate. So I decided to use x, y, z notation but I wrote
some macros that could help me in reducing the triplification of code
that may happen at some places:
Almost certainly your compiler won't insert padding between the doubles
in the struct, so you can just cast a vector * to double * to treat it
as an array.

Aug 1 '08 #2
In article <ef**********************************@v39g2000pro. googlegroups.com>,
pereges <Br*****@gmail.comwrote:
>Hello, I have the following structure -
typedef struct
{
double x, y, z;

}vector;

In certain places, I could avoid triplification of code by using an
array instead of x, y, z. For eg:

typedef struct
{
double coord[3];

} vector;

But this notation does not some people who are going to read my code
(physics people). They are used to x, y, z notation for vectors. Also
I use long expressions in some places and using coord[index] makes it
even more intricate. So I decided to use x, y, z notation but I wrote
some macros that could help me in reducing the triplification of code
that may happen at some places:

#define coord[0] x
#define coord[1] y
#define coord[2] z

I thought this will allow array indexing of the coordinates but
instead I got an error "coord redefined" . Why is that ?
Because macros can't be in "array form" and instead what you've
done is #define coord three times :) I can probably imagine
the triplication of code you're referring to, but what the hey,
before looking at solutions, can you show an example of the
two ways you're talking about, and what you see is their
respective pros and cons?
--
Greg Comeau / 4.3.10.1 with C++0xisms now in beta!
Comeau C/C++ ONLINE == http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
Aug 1 '08 #3
In article <ef**********************************@v39g2000pro. googlegroups.com>,
pereges <Br*****@gmail.comwrote:
>#define coord[0] x
Try

#define x coord[0]
--
"After all, what problems has intellectualism ever solved?"
-- Robert Gilman
Aug 1 '08 #4
pereges wrote:
Hello, I have the following structure -

typedef struct
{
double x, y, z;

}vector;

In certain places, I could avoid triplification of code by using an
array instead of x, y, z. For eg:

typedef struct
{
double coord[3];

} vector;

But this notation does not some people who are going to read my code
(physics people). They are used to x, y, z notation for vectors. Also
I use long expressions in some places and using coord[index] makes it
even more intricate. So I decided to use x, y, z notation but I wrote
some macros that could help me in reducing the triplification of code
that may happen at some places:

#define coord[0] x
#define coord[1] y
#define coord[2] z

I thought this will allow array indexing of the coordinates but
instead I got an error "coord redefined" . Why is that ?
Because `coord[0]' and the rest are not valid identifiers for
macros (or for anything else, either). `coord[0]' is a sequence
of four tokens (formally "pp-tokens"): `coord', `[', `0', and `]',
and a macro name must be a single token -- more, it must be a single
token that is a valid identifier.

You could do things the other way around:

#define x coord[0]
#define y coord[1]
#define z coord[2]
...
norm = sqrt(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z);

where macro replacement transforms the final line to

norm = sqrt(vec.coord[0] * vec.coord[0]
+ vec.coord[1] * vec.coord[1]
+ vec.coord[2] * vec.coord[2]);

However, I wouldn't recommend this. The preprocessor will replace
every `x', `y', and `z' it can find, even in unsuitable contexts:

double x = (vec1.x + vec2.x) * 0.5;

becomes

double coord[0] = (vec1.coord[0] + vec2.coord[0]) * 0.5;

.... and this is likely to create confusion, in addition to the
compile-time diagnostic message.

It is tempting, just as many sins are tempting, to define the
struct with three elements x,y,z and then pretend it's really an
array when you want to loop over them:

vector vec = ...;
int i;
/* Find the opposite vector: */
for (i = 0; i < 3; ++i)
*(&vec.x + i) *= -1;

This may even work as intended in a lot of situations, but since
it sneaks behind the compiler's back to modify vec.y and vec.z
without ever mentioning them, an optimizer might mistakenly think
they aren't being modified and this could lead to chaos. Maybe not
today, but when your compiler gets smarter at the next release ...

Just how much "triplification" are you trying to avoid, anyhow?

--
Er*********@sun.com
Aug 1 '08 #5
"pereges" <Br*****@gmail.comwrote in message
news:ef**********************************@v39g2000 pro.googlegroups.com...
Hello, I have the following structure -

typedef struct
{
double x, y, z;

}vector;

In certain places, I could avoid triplification of code by using an
array instead of x, y, z. For eg:

typedef struct
{
double coord[3];

} vector;
I tried this:

typedef struct
{
union {
struct {double x, y, z;};
double coord[3];
};

}vector;

This allows you to access the vector as .x .y .z or as .coord[0] .coord[1]
..coord[2]. No macros needed.

However you need a compiler that allows anonymous unions and structs.

--
Bartc

Aug 1 '08 #6
pereges said:
Hello, I have the following structure -

typedef struct
{
double x, y, z;

}vector;

In certain places, I could avoid triplification of code by using an
array instead of x, y, z. For eg:

typedef struct
{
double coord[3];

} vector;

But this notation does not some people who are going to read my code
(physics people). They are used to x, y, z notation for vectors. Also
I use long expressions in some places and using coord[index] makes it
even more intricate. So I decided to use x, y, z notation but I wrote
some macros that could help me in reducing the triplification of code
that may happen at some places:

#define coord[0] x
#define coord[1] y
#define coord[2] z

I thought this will allow array indexing of the coordinates but
instead I got an error "coord redefined" . Why is that ?

Your question has already been answered, but I have a suggestion for you:

#define X 0
#define Y 1
#define Z 2

If your physicist can't understand coord[X] to mean the X coordinate, then
he's probably not much of a physicist.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 1 '08 #7
Bartc wrote:
) I tried this:
)
) typedef struct
) {
) union {
) struct {double x, y, z;};
) double coord[3];
) };
)
) }vector;
)
) This allows you to access the vector as .x .y .z or as .coord[0] .coord[1]
) .coord[2]. No macros needed.
)
) However you need a compiler that allows anonymous unions and structs.

And one where nothing bad happens as a result of the undefined behaviour
you just invoked.
SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
Aug 1 '08 #8
Eric Sosman <Er*********@sun.comwrites:
pereges wrote:
>Hello, I have the following structure -
typedef struct
{
double x, y, z;
}vector;
In certain places, I could avoid triplification of code by using an
array instead of x, y, z. For eg:
typedef struct
{
double coord[3];
} vector;
But this notation does not some people who are going to read my code
(physics people). They are used to x, y, z notation for vectors. Also
I use long expressions in some places and using coord[index] makes it
even more intricate. So I decided to use x, y, z notation but I wrote
some macros that could help me in reducing the triplification of code
that may happen at some places:
#define coord[0] x
#define coord[1] y
#define coord[2] z
I thought this will allow array indexing of the coordinates but
instead I got an error "coord redefined" . Why is that ?

Because `coord[0]' and the rest are not valid identifiers for
macros (or for anything else, either). `coord[0]' is a sequence
of four tokens (formally "pp-tokens"): `coord', `[', `0', and `]',
and a macro name must be a single token -- more, it must be a single
token that is a valid identifier.

You could do things the other way around:

#define x coord[0]
#define y coord[1]
#define z coord[2]
...
norm = sqrt(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z);

where macro replacement transforms the final line to

norm = sqrt(vec.coord[0] * vec.coord[0]
+ vec.coord[1] * vec.coord[1]
+ vec.coord[2] * vec.coord[2]);

However, I wouldn't recommend this. The preprocessor will replace
every `x', `y', and `z' it can find, even in unsuitable contexts:

double x = (vec1.x + vec2.x) * 0.5;

becomes

double coord[0] = (vec1.coord[0] + vec2.coord[0]) * 0.5;

... and this is likely to create confusion, in addition to the
compile-time diagnostic message.
[...]

A possible way to avoid this potential problem is to take advantage of
the convention that macro names are (usually) in all-caps. For example:

typedef struct {
double coord[3];
} vector;
#define X coord[0]
#define Y coord[1]
#define Z coord[2]

...

double x = (vec1.X + vec2.X) * 0.5;

Just make sure not to use the names X, Y, and Z for anything else.
You can use still x, y, and z for other things (if you must).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Aug 1 '08 #9
Richard Heathfield <rj*@see.sig.invalidwrites:
[...]
Your question has already been answered, but I have a suggestion for you:

#define X 0
#define Y 1
#define Z 2

If your physicist can't understand coord[X] to mean the X coordinate, then
he's probably not much of a physicist.
A nearly equivalent alternative is:

enum { X = 0, Y = 1, Z = 2 };

The initializers aren't actually necessary, but sometimes it's good to
be more explicit than you have to be.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Aug 1 '08 #10
Keith Thompson said:

<snip>
A possible way to avoid this potential problem is to take advantage of
the convention that macro names are (usually) in all-caps. For example:

typedef struct {
double coord[3];
} vector;
#define X coord[0]
#define Y coord[1]
#define Z coord[2]

...

double x = (vec1.X + vec2.X) * 0.5;

Just make sure not to use the names X, Y, and Z for anything else.
You can use still x, y, and z for other things (if you must).
And another way to avoid this whole mess is not to use macros at all!

typedef struct
{
double *coord[3];
double x;
double y;
double z;
} vector;

although this does involve some setup for every vector used:

void vector_initialise(vector *p)
{
p->coord[0] = &p->x;
p->coord[1] = &p->y;
p->coord[2] = &p->z;
}

and it means that, in your array processing, you have to deref:

for(dim = 0; dim < 2; dim++)
{
dist += *p->coord[dim] * *p->coord[dim];
}

Whether you consider this game to be worth the candle is obviously up to
you, but it's a technique I have found useful on occasion.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 1 '08 #11
On 1 Aug 2008 at 22:15, Richard Heathfield wrote:
typedef struct
{
double *coord[3];
double x;
double y;
double z;
} vector;

although this does involve some setup for every vector used:

void vector_initialise(vector *p)
{
p->coord[0] = &p->x;
p->coord[1] = &p->y;
p->coord[2] = &p->z;
}
Wonderful!

Time and again Heathfield has shown us that he has a casual disregard
for gross inefficiencies in his programming, but this takes the biscuit.

The OP explicitly says his main aim is to avoid triplication, so
Heathfield proposes a maintenance nightmare that involves keeping
triplicate copies of data in sync at all times. Unbelievable.

Once again, the solution is very simple: just cast vector* to double*.

Aug 1 '08 #12
On Aug 1, 3:52*pm, pereges <Brol...@gmail.comwrote:
Hello, I have the following structure -

typedef struct
{
* *double x, y, z;

}vector;

In certain places, I could avoid triplification of code by using an
array instead of x, y, z. For eg:

typedef struct
{
* *double coord[3];

} vector;

But this notation does not some people who are going to read my code
(physics people). They are used to x, y, z notation for vectors. Also
I use long expressions in some places and using coord[index] makes it
even more intricate. So I decided to use x, y, z notation but I wrote
some macros that could help me in reducing the triplification of code
that may happen at some places:

#define coord[0] * * x
#define coord[1] * * y
#define coord[2] * * z

I thought this will allow array indexing of the coordinates but
instead I got an error "coord redefined" . Why is that ?

While heresy around here, if you're actually writing C++ (or can),
getters and setters named x, y and z will solve the problem nicely.
Aug 1 '08 #13

"Antoninus Twink" <no****@nospam.invalidwrote in message
news:sl*******************@nospam.invalid...
On 1 Aug 2008 at 22:15, Richard Heathfield wrote:
>typedef struct
{
double *coord[3];
double x;
double y;
double z;
} vector;

although this does involve some setup for every vector used:

void vector_initialise(vector *p)
{
p->coord[0] = &p->x;
p->coord[1] = &p->y;
p->coord[2] = &p->z;
}

Wonderful!

Time and again Heathfield has shown us that he has a casual disregard
for gross inefficiencies in his programming, but this takes the biscuit.

The OP explicitly says his main aim is to avoid triplication, so
Heathfield proposes a maintenance nightmare that involves keeping
triplicate copies of data in sync at all times. Unbelievable.

Once again, the solution is very simple: just cast vector* to double*.
For this to work the fields x,y,z need to be stored in memory in the same
way as three consecutive array elements.

Apparently there are machines around where this may not be true. I think
this was the objection to my idea.

--
Bartc

Aug 1 '08 #14
On 1 Aug 2008 at 22:54, Bartc wrote:
>Once again, the solution is very simple: just cast vector* to double*.

For this to work the fields x,y,z need to be stored in memory in the same
way as three consecutive array elements.

Apparently there are machines around where this may not be true. I think
this was the objection to my idea.
I suspect these machines exist only in the minds of the "regulars".

On most modern hardware, doubles will be 64-bit aligned and a struct
with three double fields will not be padded.

The OP can double-check this if necessary, and if by some freak chance
it does turn out to be a problem, his compiler probably has a way to let
him forced no structure padding, e.g. in gcc __attribute__
((__packed__)).

Aug 1 '08 #15
ro***********@yahoo.com wrote:
>
While heresy around here, if you're actually writing C++ (or can),
getters and setters named x, y and z will solve the problem nicely.
If you were using C++, you probably wouldn't care about the internal
representation!

--
Ian Collins.
Aug 1 '08 #16
"Bartc" <bc@freeuk.comwrites:
"Antoninus Twink" <no****@nospam.invalidwrote in message
news:sl*******************@nospam.invalid...
<snip>
>Once again, the solution is very simple: just cast vector* to double*.

For this to work the fields x,y,z need to be stored in memory in the
same way as three consecutive array elements.

Apparently there are machines around where this may not be true. I
think this was the objection to my idea.
The OP can guard against that by checking that

offsetof(struct vector, z) == 2 * sizeof(double)

but I favour making it an array defining an enum to index it. Of
course you then have a redundant member name that you have to keep
writing, so there is some merit in at least considering:

enum { X = 0, Y = 1, Z = 2, Dimensions = 3 };
typedef double vector[Dimensions];

You can't pass one by value to a function, of course, but then I doubt
that matters for this application. The code is quite readable this way:

vector norm;
norm[Z] = norm[X] + norm[Y];

--
Ben.
Aug 2 '08 #17
In article <sl*******************@nospam.invalid>,
Antoninus Twink <no****@nospam.invalidwrote:
>On 1 Aug 2008 at 22:54, Bartc wrote:
>>Once again, the solution is very simple: just cast vector* to double*.
>On most modern hardware, doubles will be 64-bit aligned and a struct
with three double fields will not be padded.
It isn't uncommon for doubles to be 32 bit aligned, same as float.

--
"The quirks and arbitrariness we observe force us to the
conclusion that ours is not the only universe." -- Walter Kistler
Aug 2 '08 #18
Ian Collins said:
ro***********@yahoo.com wrote:
>>
While heresy around here, if you're actually writing C++ (or can),
getters and setters named x, y and z will solve the problem nicely.

If you were using C++, you probably wouldn't care about the internal
representation!
You would if you were reading the code, though, surely?

The OP said: "But this notation does not [suit? meet with the approval of?]
some people who are going to read my code (physics people)."

It is not unreasonable to suppose that they might need to read the class
code (in a C++ version of the program), and thus /will/ (or at least may)
care about the internal representation.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 2 '08 #19
Richard Heathfield wrote:
Ian Collins said:
>ro***********@yahoo.com wrote:
>>While heresy around here, if you're actually writing C++ (or can),
getters and setters named x, y and z will solve the problem nicely.
If you were using C++, you probably wouldn't care about the internal
representation!

You would if you were reading the code, though, surely?
That depends how the code was written. In C++ a vector could be written
as a black box to the user, all operations on the vector being defined
as members.
The OP said: "But this notation does not [suit? meet with the approval of?]
some people who are going to read my code (physics people)."
Possibly because you have to work at a lower level in C.
It is not unreasonable to suppose that they might need to read the class
code (in a C++ version of the program), and thus /will/ (or at least may)
care about the internal representation.
I guess being "physics people" they might want to mix the code with
Fortran :)

--
Ian Collins.
Aug 2 '08 #20
ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) writes:
[...]
It isn't uncommon for doubles to be 32 bit aligned, same as float.
It's not possible for any type to have an alignment requirement larger
than its size. An array of any type cannot have gaps between the
elements.

For a structure all of whose members are of the same type, a compiler
is *allowed* to insert padding between the members, but I can think of
no good reason for it to do so (though it may well have a reason to
insert padding at the end).

Nevertheless, I personally prefer not to depend on this kind of thing,
especially when there are other solutions. And if for some reason I
decided to depend on this, I'd add a check so the program aborts
quickly in the unlikely event that there *are* gaps between the
members.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Aug 2 '08 #21

"Richard Heathfield" <rj*@see.sig.invalidwrote in message
>
Your question has already been answered, but I have a suggestion for you:

#define X 0
#define Y 1
#define Z 2

If your physicist can't understand coord[X] to mean the X coordinate, then
he's probably not much of a physicist.
It's not a bad idea. The problem is that a less clever person, lets say a C
programmer, might look at that and say "Hummm, X is some sort of variable
that iterates over a coordinate set. But I don't see it in scope. What on
Earth is going on here?"

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Aug 2 '08 #22
Well triplification of code does happen and it makes the code look
ugly. I can't pick out a specific example from my project but usually
it happens when you want something to be done with only one coordinate
of vector and not all. For eg. in my kdtree building module, I have
to find the median of the vertices(vectors) along x, y or z
coordinates based on the value of a flag called splitplane. This
splitplane may take values 0, 1, 2 (0 means split along x, 1 means
split along y, 2 means split along z). If this notation was used -

typedef struct
{
double coord[3];

}vector;

vector v;

Now, when I find to find out median of many such vectors along some
axis given by splitplane flag, I simply need to specify
v.coord[splitplane] to the median finding algorithm whereas if this
notation is followed -

typedef struct
{
double x, y, z;

}vector;

vector v;

I have to do something like below :

if (splitplane == 0)
{
/* Find median along x */

}

if (splitplane == 1)
{
/* Find median along y */
}

if (splitplane == 2)
{
/* Find median along z */
}

This is what I mean by "triplification". Here, the logic behind
finding the median is same but it will be repeated thrice.

Anyway, I came up with another solution and that is to use a vector
iterator function like below :

double vector_iterator(vector v, int axis)
{
if (axis == 0)
{
return (v.x);
}

if (axis == 1)
{
return (v.y);
}

if (axis == 2)
{
return (v.z);
}
}

This will reduce some work. What do you think ?
Aug 2 '08 #23

"pereges" <Br*****@gmail.comwrote in message
news:44**********************************@v1g2000p ra.googlegroups.com...
....
Anyway, I came up with another solution and that is to use a vector
iterator function like below :

double vector_iterator(vector v, int axis)
{
if (axis == 0)
{
return (v.x);
}

if (axis == 1)
{
return (v.y);
}

if (axis == 2)
{
return (v.z);
}
}

This will reduce some work. What do you think ?
How about shortening to:

switch (axis) {
case 0: return v.x;
case 1: return v.y;
case 2: return v.z;
...?

It would also be tempting to use: return *(&v.x+axis) although this sort of
code is frowned on in this group.
double vector_iterator(vector v, int axis)
Are you really passing the entire struct here? Best to use a pointer to it
then use v-instead of v.

--
Bartc

Aug 2 '08 #24
On Aug 2, 5:02 pm, "Bartc" <b...@freeuk.comwrote:
How about shortening to:

switch (axis) {
case 0: return v.x;
case 1: return v.y;
case 2: return v.z;
...?

It would also be tempting to use: return *(&v.x+axis) although this sort of
code is frowned on in this group.
double vector_iterator(vector v, int axis)

Are you really passing the entire struct here? Best to use a pointer to it
then use v-instead of v.
Agree with you about the switch case. I also think it will be better
to return the address of the coordinate rather than its value. Here's
a small program that I tried with this approach:

#include <stdio.h>

typedef struct
{
double x, y, z;

}vector;

double *vector_iterator(vector *v, int axis)
{
switch (axis)
{
case 0: return (&v->x);
case 1: return (&v->y);
case 2: return (&v->z);
}
}

int main(void)
{
vector v;

v.x = 5;
v.y = 3;
v.z = 2;

*(vector_iterator(&v, 0)) = 3; /* Note this */
printf("%f", v.x);
return 0;
}

This is fine with my compiler (Output is 3.000000), but I'm unsure
about function call on the left side of = operator (lvalue ?)
Aug 2 '08 #25
pereges <Br*****@gmail.comwrites:
<snip>
Anyway, I came up with another solution and that is to use a vector
iterator function like below :

double vector_iterator(vector v, int axis)
{
if (axis == 0)
{
return (v.x);
}

if (axis == 1)
{
return (v.y);
}

if (axis == 2)
{
return (v.z);
}
}

This will reduce some work. What do you think ?
There is an old programming rule "pass data to functions, not control"
which this function violates (somewhat). If you keep your vectors as
structs (and I've suggested an alternative elsewhere) then I would
write any functions that need to something with programmatically
selected members like this:

typedef double (*selector)(vector *);

inline double get_x(vector *vp) { return vp->x; }
inline double get_y(vector *vp) { return vp->y; }
inline double get_z(vector *vp) { return vp->z; }

double average_of(vector *v, size_t n, selector axis)
{
double sum = 0;
for (size_t i = 0; i < n; i++)
sum += axis(&v[i]);
return sum / n;
}

Obviously, if you need numerical control you can have the selectors in
an array:

selector axes[] = { get_x, get_y, get_z };
....
average_of(my_vec_array, axes[i]);

--
Ben.
Aug 2 '08 #26
In article <sl*******************@nospam.invalid>,
Antoninus Twink <no****@nospam.invalidwrote:
>On 1 Aug 2008 at 22:15, Richard Heathfield wrote:
>typedef struct
{
double *coord[3];
double x;
double y;
double z;
} vector;

although this does involve some setup for every vector used:

void vector_initialise(vector *p)
{
p->coord[0] = &p->x;
p->coord[1] = &p->y;
p->coord[2] = &p->z;
}

Wonderful!

Time and again Heathfield has shown us that he has a casual disregard
for gross inefficiencies in his programming, but this takes the biscuit.

The OP explicitly says his main aim is to avoid triplication, so
Heathfield proposes a maintenance nightmare that involves keeping
triplicate copies of data in sync at all times. Unbelievable.
Let's assume this is so (I'm not saying it is, just to assume so)...
>Once again, the solution is very simple: just cast vector* to double*.
.... the problem is that your way makes some assumptions (which I seem
to recall you clearly stated when you posted it about padding, or not,
in the struct), however, that is also a maintenance nightmare,
since as you noted, there may or may not be padding. And on machines
where there is, it won't even work. How many machines is that in popular
use? Dunno, probably not many. But it doesn't negate your point :)
--
Greg Comeau / 4.3.10.1 with C++0xisms now in beta!
Comeau C/C++ ONLINE == http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
Aug 2 '08 #27
"Malcolm McLean" <re*******@btinternet.comwrites:
"Richard Heathfield" <rj*@see.sig.invalidwrote in message
>Your question has already been answered, but I have a suggestion for you:

#define X 0
#define Y 1
#define Z 2

If your physicist can't understand coord[X] to mean the X coordinate, then
he's probably not much of a physicist.
It's not a bad idea. The problem is that a less clever person, lets
say a C programmer, might look at that and say "Hummm, X is some sort
of variable that iterates over a coordinate set. But I don't see it in
scope. What on Earth is going on here?"
A C programmer is more likely to assume, correctly, that X is likely
to be a macro because its name is in all-caps.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Aug 2 '08 #28
On 2 Aug 2008 at 16:38, Greg Comeau wrote:
Antoninus Twink <no****@nospam.invalidwrote:
>>On 1 Aug 2008 at 22:15, Richard Heathfield wrote:
>>typedef struct
{
double *coord[3];
double x;
double y;
double z;
} vector;

void vector_initialise(vector *p)
{
p->coord[0] = &p->x;
p->coord[1] = &p->y;
p->coord[2] = &p->z;
}

The OP explicitly says his main aim is to avoid triplication, so
Heathfield proposes a maintenance nightmare that involves keeping
triplicate copies of data in sync at all times. Unbelievable.

Let's assume this is so (I'm not saying it is, just to assume so)...
Oops, yes, good spot - I'd scanned Heathfield's code too quickly. So in
fact you only need to set it up once (which would be fine in a language
with ctors like C++ but is annoying in C), but then you need an ugly
extra level of indirection every time you want to access it as an array.
Still yuck.

Aug 2 '08 #29
Greg Comeau said:
In article <sl*******************@nospam.invalid>,
Antoninus Twink <no****@nospam.invalidwrote:
>>On 1 Aug 2008 at 22:15, Richard Heathfield wrote:
>>typedef struct
{
double *coord[3];
double x;
double y;
double z;
} vector;

although this does involve some setup for every vector used:

void vector_initialise(vector *p)
{
p->coord[0] = &p->x;
p->coord[1] = &p->y;
p->coord[2] = &p->z;
}

Wonderful!

Time and again Heathfield has shown us that he has a casual disregard
for gross inefficiencies in his programming, but this takes the biscuit.

The OP explicitly says his main aim is to avoid triplication, so
Heathfield proposes a maintenance nightmare that involves keeping
triplicate copies of data in sync at all times. Unbelievable.

Let's assume this is so
No, let's not, because he's wrong.
(I'm not saying it is, just to assume so)...
I understand why it is sometimes useful to make questionable assumptions
(for example, it's a sine qua non in an r.a.a. proof), but I see no value
in it here. He's simply wrong. There is no maintenance nightmare, just a
small set-up cost. There is no need to keep triplicate copies of data in
sync at all times, since my proposed method doesn't make any copies of the
data whatsoever.

It seems pretty clear to me that the guy just can't read clearly or think
objectively...
>>Once again, the solution is very simple: just cast vector* to double*.
....and really really sucks at C.
... the problem is that your way makes some assumptions (which I seem
to recall you clearly stated when you posted it about padding, or not,
in the struct), however, that is also a maintenance nightmare,
since as you noted, there may or may not be padding. And on machines
where there is, it won't even work. How many machines is that in popular
use? Dunno, probably not many. But it doesn't negate your point :)
His point, such as it is, is negated by the fact that it isn't true, and
his counter-point is negated by the fact that it breaches the rules of the
language.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 2 '08 #30
On 2 Aug 2008 at 17:04, Keith Thompson wrote:
"Malcolm McLean" <re*******@btinternet.comwrites:
>It's not a bad idea. The problem is that a less clever person, lets
say a C programmer, might look at that and say "Hummm, X is some sort
of variable that iterates over a coordinate set. But I don't see it in
scope. What on Earth is going on here?"

A C programmer is more likely to assume, correctly, that X is likely
to be a macro because its name is in all-caps.
That would be true if the name was more than one character long.

Aug 2 '08 #31
In article <sl*******************@nospam.invalid>,
Antoninus Twink <no****@nospam.invalidwrote:
>On 2 Aug 2008 at 16:38, Greg Comeau wrote:
>Antoninus Twink <no****@nospam.invalidwrote:
>>>On 1 Aug 2008 at 22:15, Richard Heathfield wrote:
typedef struct
{
double *coord[3];
double x;
double y;
double z;
} vector;

void vector_initialise(vector *p)
{
p->coord[0] = &p->x;
p->coord[1] = &p->y;
p->coord[2] = &p->z;
}

The OP explicitly says his main aim is to avoid triplication, so
Heathfield proposes a maintenance nightmare that involves keeping
triplicate copies of data in sync at all times. Unbelievable.

Let's assume this is so (I'm not saying it is, just to assume so)...

Oops, yes, good spot - I'd scanned Heathfield's code too quickly. So in
fact you only need to set it up once (which would be fine in a language
with ctors like C++ but is annoying in C), but then you need an ugly
extra level of indirection every time you want to access it as an array.
Still yuck.
Well, the machinery IS interesting, and sometimes that is necessary.
For better and for worse.

I believe that OP finally posted some more about the intent of the
original query, so I guess we'll see more about which solution
set seems to make the most sense now.
--
Greg Comeau / 4.3.10.1 with C++0xisms now in beta!
Comeau C/C++ ONLINE == http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
Aug 2 '08 #32
On Fri, 01 Aug 2008 21:34:34 GMT, "Bartc" <bc@freeuk.comwrote:
>"pereges" <Br*****@gmail.comwrote in message
news:ef**********************************@v39g200 0pro.googlegroups.com...
>Hello, I have the following structure -

typedef struct
{
double x, y, z;

}vector;

In certain places, I could avoid triplification of code by using an
array instead of x, y, z. For eg:

typedef struct
{
double coord[3];

} vector;

I tried this:

typedef struct
{
union {
struct {double x, y, z;};
double coord[3];
};

}vector;

This allows you to access the vector as .x .y .z or as .coord[0] .coord[1]
.coord[2]. No macros needed.

However you need a compiler that allows anonymous unions and structs.
And one that promises not to insert padding. coord[0] is guaranteed
to overlay x but the same is not true for the remaining members.

--
Remove del for email
Aug 2 '08 #33
On Aug 2, 5:29 pm, pereges <Brol...@gmail.comwrote:
On Aug 2, 5:02 pm, "Bartc" <b...@freeuk.comwrote:
How about shortening to:
switch (axis) {
case 0: return v.x;
case 1: return v.y;
case 2: return v.z;
...?
It would also be tempting to use: return *(&v.x+axis) although this sort of
code is frowned on in this group.
double vector_iterator(vector v, int axis)
Are you really passing the entire struct here? Best to use a pointer to it
then use v-instead of v.

Agree with you about the switch case. I also think it will be better
to return the address of the coordinate rather than its value. Here's
a small program that I tried with this approach:

#include <stdio.h>

typedef struct
{
double x, y, z;

}vector;

double *vector_iterator(vector *v, int axis)
{
switch (axis)
{
case 0: return (&v->x);
case 1: return (&v->y);
case 2: return (&v->z);
}

}

int main(void)
{
vector v;

v.x = 5;
v.y = 3;
v.z = 2;

*(vector_iterator(&v, 0)) = 3; /* Note this */
printf("%f", v.x);
return 0;

}

This is fine with my compiler (Output is 3.000000), but I'm unsure
about function call on the left side of = operator (lvalue ?)
By the way, with this code I get a warning :

$ gcc -W -Wall -ansi -pedantic -O2 foo.c
foo.c: In function `vector_iterator':
foo.c:18: warning: control reaches end of non-void function

I actually got this warning in many other programs when there was no
return value specified at the end of the function. I could return NULL
at the end of course(and then use assert before you store value at the
address), but the control will never reach that stage unless the
precondition within the function are not satisfied. I don't know if I
should absolutely get rid of this warning.
Aug 2 '08 #34
pereges wrote:
On Aug 2, 5:29 pm, pereges <Brol...@gmail.comwrote:
>On Aug 2, 5:02 pm, "Bartc" <b...@freeuk.comwrote:
How about shortening to:
switch (axis) {
case 0: return v.x;
case 1: return v.y;
case 2: return v.z;
...?
It would also be tempting to use: return *(&v.x+axis) although this
sort of code is frowned on in this group.
double vector_iterator(vector v, int axis)
Are you really passing the entire struct here? Best to use a
pointer to it then use v-instead of v.

Agree with you about the switch case. I also think it will be better
to return the address of the coordinate rather than its value. Here's
a small program that I tried with this approach:

#include <stdio.h>

typedef struct
{
double x, y, z;

}vector;

double *vector_iterator(vector *v, int axis)
{
switch (axis)
{
case 0: return (&v->x);
case 1: return (&v->y);
case 2: return (&v->z);
}

}

int main(void)
{
vector v;

v.x = 5;
v.y = 3;
v.z = 2;

*(vector_iterator(&v, 0)) = 3; /* Note this */
printf("%f", v.x);
return 0;

}

This is fine with my compiler (Output is 3.000000), but I'm unsure
about function call on the left side of = operator (lvalue ?)

By the way, with this code I get a warning :

$ gcc -W -Wall -ansi -pedantic -O2 foo.c
foo.c: In function `vector_iterator':
foo.c:18: warning: control reaches end of non-void function

I actually got this warning in many other programs when there was no
return value specified at the end of the function.
When control reaches the terminating brace of a non-void function then
an indeterminate value (i.e., garbage) is returned to the caller. You
should always return a sensible value for all non-void functions. If
you do not want to return any value from a function just declare that
function as returning void.

<snip>

For the specific function you might want to include a default case for
invalid parameter values. This could return NULL.

Aug 2 '08 #35
"Richard Heathfield" <rj*@see.sig.invalidwrote in message
news:HO******************************@bt.com...
Greg Comeau said:
>In article <sl*******************@nospam.invalid>,
Antoninus Twink <no****@nospam.invalidwrote:
>>>On 1 Aug 2008 at 22:15, Richard Heathfield wrote:
typedef struct
{
double *coord[3];
double x;
double y;
double z;
} vector;

although this does involve some setup for every vector used:

void vector_initialise(vector *p)
{
p->coord[0] = &p->x;
p->coord[1] = &p->y;
p->coord[2] = &p->z;
}

Wonderful!

Time and again Heathfield has shown us that he has a casual disregard
for gross inefficiencies in his programming, but this takes the biscuit.

The OP explicitly says his main aim is to avoid triplication, so
Heathfield proposes a maintenance nightmare that involves keeping
triplicate copies of data in sync at all times. Unbelievable.

Let's assume this is so

No, let's not, because he's wrong.
>(I'm not saying it is, just to assume so)...

I understand why it is sometimes useful to make questionable assumptions
(for example, it's a sine qua non in an r.a.a. proof), but I see no value
in it here. He's simply wrong. There is no maintenance nightmare, just a
small set-up cost. There is no need to keep triplicate copies of data in
sync at all times, since my proposed method doesn't make any copies of the
data whatsoever.
As I understand it, you're adding 3 pointers to each struct containing x,y,z
doubles, and the pointers are set up to point to each of the x,y,z fields.

Apart the inconvenience and extra space and extra dereferencing, I can see
this causing problems when such a struct is passed by value to a function,
or copied by assignment to another struct: the pointers will point to the
fields in the original struct, not the copy.

--
Bartc

Aug 2 '08 #36
Bartc said:

<snip>
As I understand it, you're adding 3 pointers to each struct containing
x,y,z doubles, and the pointers are set up to point to each of the x,y,z
fields.
Right.
Apart the inconvenience and extra space and extra dereferencing,
Right again. There ain't no such thing as a free lunch. Perhaps there's a
better approach that will solve the OP's problem, but I haven't seen it
yet. Any suggestions?
I can
see this causing problems when such a struct is passed by value to a
function, or copied by assignment to another struct: the pointers will
point to the fields in the original struct, not the copy.
Right again again. In practice, the first of these is easily avoided simply
by avoiding passing structs by value, and many people already avoid this
for other good reasons. The second isn't a problem if you use a "deep
copy" technique rather than simple assignment. Alternatively, you can do
your pass-by-value or assignment if you insist, provided that you remember
to call, immediately afterwards, the pointer initialisation routine that I
supplied.

Now, I'm perfectly prepared to accept that this isn't an ideal solution,
and I'm certainly prepared to accept that someone may come up with a
better idea that meets the OP's needs better whilst remaining correct C.
But I haven't yet seen anyone post such an idea.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 2 '08 #37
pereges <Br*****@gmail.comwrites:
On Aug 2, 5:29 pm, pereges <Brol...@gmail.comwrote:
[...]
>#include <stdio.h>

typedef struct
{
double x, y, z;

}vector;

double *vector_iterator(vector *v, int axis)
{
switch (axis)
{
case 0: return (&v->x);
case 1: return (&v->y);
case 2: return (&v->z);
}

}
[...]
By the way, with this code I get a warning :

$ gcc -W -Wall -ansi -pedantic -O2 foo.c
foo.c: In function `vector_iterator':
foo.c:18: warning: control reaches end of non-void function

I actually got this warning in many other programs when there was no
return value specified at the end of the function. I could return NULL
at the end of course(and then use assert before you store value at the
address), but the control will never reach that stage unless the
precondition within the function are not satisfied. I don't know if I
should absolutely get rid of this warning.
You can get rid of the warning by adding a default case:

...
default: return NULL;

You're getting the warning because the compiler has no way of knowing
that the value of axis will always be in the range [0, 2].

Incidentally, this might be a good place for an assert(), something
like:

double *vector_iterator(vector *v, int axis)
{
assert(axis >= 0 && axis <= 2);
switch (axis) {
case 0: return &v->x;
case 1: return &v->y;
case 2: return &v->z;
default: return NULL;
}
}

The assumption is that an axis value outside that range is a
programming error, not a data error. If there's a possibility of the
axis value being derived from user or file input, you should handle it
as a data error, not using assert().

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Aug 2 '08 #38
In article <44**********************************@v1g2000pra.g ooglegroups.com>
pereges <Br*****@gmail.comwrote:

[I did some vertical compression below just for quote-shortening purposes]
>... usually [the code duplication] happens when you want something
to be done with only one coordinate of vector and not all. For eg.
in my kdtree building module, I have to find the median of the
vertices(vectors) along x, y or z coordinates based on the value
of a flag called splitplane. This splitplane may take values 0, 1,
2 (0 means split along x, 1 means split along y, 2 means split
along z). If this notation was used -

typedef struct { double coord[3]; } vector;

... I simply need to specify v.coord[splitplane] ... whereas if this
notation is followed -

typedef struct { double x, y, z; } vector;

I have to do something like below :

if (splitplane == 0) { /* Find median along x */ }
if (splitplane == 1) { /* Find median along y */ }
if (splitplane == 2) { /* Find median along z */ }

This is what I mean by "triplification". Here, the logic behind
finding the median is same but it will be repeated thrice.
Elsethread, others have suggested various approaches. Here is one
more that is a variant of the pointer-to-element version. It is
not very pretty, but -- modulo errors (this code is untested) --
is guaranteed to work, and *may* have a lower runtime cost than
calling a function to find &vecp->x, &vecp->y, or &vecp->z.

[begin contents of vector.h]

/* Vector type, including its element-type. */
typedef double Vector_elt_type;
/*
* optionally, you might also includ
* typedef struct vector Vector_type;
* but I prefer to use the word "struct" for a type-name, except
* in cases where it is guaranteed to be an alias for a scalar
* type (as with Vector_elt_type, which is one of float, double,
* or long double).
*
* (Think of the "struct" keyword as a funny way to spell the
* word "type".)
*/
struct vector {
Vector_elt_type x, y, z;
};

/* Vector "plane selector" numbers. */
enum { VECTOR_X = 0, VECTOR_Y = 1, VECTOR_Z = 2 };

/*
* Note that these are byte offsets, so that they will work
* even if the "vector" struct is augmented with additional
* fields before, between, and/or after the three elements
* we care about, and regardless of any padding a compiler might
* use.
*/
extern const size_t vector_field_offsets[];

/*
* Given a pointer to a vector, pick the X, Y, or Z element based
* on the plane number, which must be one of VECTOR_X, VECTOR_Y,
* or VECTOR_Z.
*/
#define VECTOR_TO_ELT(vecp, plane) \
((Vector_elt_type *)((char *)(vecp) + vector_field_offsets[plane]))

[end of vector.h extract -- there might be more in there, e.g.,
prototypes for functions in vector.c]

[begin contents of vector.c]

#include "vector.h"

/*
* The initializers here assume that VECTOR_X is 0,
* VECTOR_Y is 1, and VECTOR_Z is 2. We could check this
* with a COMPILE_TIME_ASSERT macro (google for it), but
* here I do not bother.
*/
const size_t vector_field_offsets[] = {
offsetof(struct vector, x),
offsetof(struct vector, y),
offsetof(struct vector, z),
};

[end contents of vector.c, though in practice there would be more
code]

[begin contents of some vector-using C code]

#include <assert.h>
#include <stddef.h>
#include "vector.h"

/* some sort of median finding operation: */
void median_op(struct vector *vector_set, size_t nvectors, int plane) {
size_t i;
Vector_elt_type *p;
... other variables as needed ...

/*
* It is a programmer error to call this function with
* a plane that is not one of the three specified vector
* plane numbers.
*/
assert(plane == VECTOR_X || plane == VECTOR_Y || plane == VECTOR_Z);

for (i = 0; i < nvectors; i++) {
p = VECTOR_TO_ELT(&vector_set[i], plane);
... work with *p as needed to find median ...
}
}
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: gmail (figure it out) http://web.torek.net/torek/index.html
Aug 3 '08 #39
pereges said:
... this notation does not [suit?] some people
who are going to read my code (physics people).
They are used to x, y, z notation for vectors.
Physicists understand vectors as n-tuples perfectly
well. They even understand zero indexing, probably
better than most programmers!

Indeed, I think you're more likely to find the physicist
asking why you bother treating the vectors as xyz when
you should be treating them more generally as x0, x1, x2,
etc...

It's typically only the dumb computer programmers who
need to 'visualise' the vector manipulations in terms
of 2d or 3d. So who are you really doing this for? ;)

<snip>
Richard Heathfield <r...@see.sig.invalidwrote:
Your question has already been answered, but I have
a suggestion for you:

#define X 0
#define Y 1
#define Z 2

If your physicist can't understand coord[X] to mean
the X coordinate, then he's probably not much of a
physicist.
If the physicist can't understand coord[0] to mean the
'first' ordinate in the vector, then they're probably
not much of a physicist either; let alone C programmer.

In either case, if you don't think a physicist will
understand the code, why show it to them?

--
Peter
Aug 3 '08 #40
>
>#define x coord[0]
That would work, but shall we count the ways it would blow up in your face?

Frankly, I don't think there's a clean solution to the problem as stated
unless you're working with a dialect of C that allows anonymous unions or structs.
And even then, only if you can truly cast vector* to double[] as suggested elsewhere.
While that would work on every architecture I've ever used, I doubt that the
standard actually supports it.

--
-Ed Falk, fa**@despams.r.us.com
http://thespamdiaries.blogspot.com/
Aug 3 '08 #41
On 2 Aug 2008 at 20:06, Richard Heathfield wrote:
Bartc said:
>Apart the inconvenience and extra space and extra dereferencing,

Right again. There ain't no such thing as a free lunch. Perhaps there's a
better approach that will solve the OP's problem, but I haven't seen it
yet. Any suggestions?
To repeat it yet again: your solution is a C++ solution, not in the
sense that it's written in (C++ but not C), but in the sense that it
fits the approach and mindset of a C++ programmer.

The natural C solution is type-punning by casting structs. You want to
claim that this is not C? Networking is based completely on manipulating
various socket structs etc. in this way. GTK builds a vast
object-oriented framework in C in this way.

Aug 3 '08 #42
In article <sl*******************@nospam.invalid>,
Antoninus Twink <no****@nospam.invalidwrote:
>On 2 Aug 2008 at 20:06, Richard Heathfield wrote:
>Bartc said:
>>Apart the inconvenience and extra space and extra dereferencing,

Right again. There ain't no such thing as a free lunch. Perhaps there's a
better approach that will solve the OP's problem, but I haven't seen it
yet. Any suggestions?

To repeat it yet again: your solution is a C++ solution, not in the
sense that it's written in (C++ but not C), but in the sense that it
fits the approach and mindset of a C++ programmer.

The natural C solution is type-punning by casting structs. You want to
claim that this is not C? Networking is based completely on manipulating
various socket structs etc. in this way. GTK builds a vast
object-oriented framework in C in this way.
And yet, in the twisted minds of the regs, none of those things are
written in C...

Aug 4 '08 #43
Kenny McCormack wrote:
In article <sl*******************@nospam.invalid>,
Antoninus Twink <no****@nospam.invalidwrote:
>On 2 Aug 2008 at 20:06, Richard Heathfield wrote:
>>Bartc said:
Apart the inconvenience and extra space and extra dereferencing,
Right again. There ain't no such thing as a free lunch. Perhaps there's a
better approach that will solve the OP's problem, but I haven't seen it
yet. Any suggestions?
To repeat it yet again: your solution is a C++ solution, not in the
sense that it's written in (C++ but not C), but in the sense that it
fits the approach and mindset of a C++ programmer.

The natural C solution is type-punning by casting structs. You want to
claim that this is not C? Networking is based completely on manipulating
various socket structs etc. in this way. GTK builds a vast
object-oriented framework in C in this way.

And yet, in the twisted minds of the regs, none of those things are
written in C...
They are not written in 'regulars C'
o no network
o no graphics
o no GUI
o no directories
o no parallelism
o no threads
o no nothing actually :-)

--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Aug 4 '08 #44
jacob navia wrote:
>
They are not written in 'regulars C'
o no network
Right. It's the domain of other standards, not of a programming
language standard.
o no graphics
Right. It's the domain of other standards (and less formal quasi-
standards), not of a programming language standard.
o no GUI
You're repeating yourself.
o no directories
Right. It's the domain of other standards, not of a programming
language standard.
o no parallelism
Right. It's the domain of other standards, which some experts
consider premature: The state of the art, they say, is insufficiently
advanced to warrant standardization. In any event, it's not an
appropriate matter for a programming language standard. (And before
somebody hollers "Java," read the serious and sometimes virulent
criticisms that have been leveled at its attempts to parallelize.)
o no threads
You're repeating yourself.
o no nothing actually :-)
You're repeating yourself from many earlier threads. You've
told us more than once that C is a dead language, that C's lack of
features (both those mentioned above and others you've promoted)
have rendered it obsolete, that nobody uses C any more, ... And
you've been asked why, in light of this belief, you waste your own
valuable time and energy stirring the ashes of this burned-out
relic. But you've never explained your passion for the long-dead.
Will you ever do so, I wonder? Or will you say to yourself, "Jacob,
you've got better things to do than fret over rubbish" and go away?

--
Er*********@sun.com
Aug 4 '08 #45
In article <g7**********@aioe.org>, jacob navia <ja***@nospam.orgwrote:
>Kenny McCormack wrote:
....
>And yet, in the twisted minds of the regs, none of those things are
written in C...

They are not written in 'regulars C'
o no network
o no graphics
o no GUI
o no directories
o no parallelism
o no threads
o no nothing actually :-)
You are absolutely right, of course.

But I want to add (and this was my original point) that in the regs
view, it isn't C. Period. Full stop, as some of them are want to say.

To which, of course, sensible people ask: Well, if it isn't C, what is it?
To which the regs say: It is "C with extensions".
To which, of course, sensible people point out that toast with jelly is
(and this, I know, will come as a big shock and a crushing blow to the
regs) still toast.

Aug 4 '08 #46
Eric Sosman wrote:
jacob navia wrote:
>>
They are not written in 'regulars C'
o no network

Right. It's the domain of other standards, not of a programming
language standard.
>o no graphics

Right. It's the domain of other standards (and less formal quasi-
standards), not of a programming language standard.
>o no GUI

You're repeating yourself.
>o no directories

Right. It's the domain of other standards, not of a programming
language standard.
>o no parallelism

Right. It's the domain of other standards, which some experts
consider premature: The state of the art, they say, is insufficiently
advanced to warrant standardization. In any event, it's not an
appropriate matter for a programming language standard. (And before
somebody hollers "Java," read the serious and sometimes virulent
criticisms that have been leveled at its attempts to parallelize.)
>o no threads

You're repeating yourself.
>o no nothing actually :-)

You're repeating yourself from many earlier threads. You've
told us more than once that C is a dead language,
You are lying, as always
that C's lack of
features (both those mentioned above and others you've promoted)
have rendered it obsolete,
same lie
that nobody uses C any more, ...
same lie
What I DID say is that people like you are killing the language
making any development impossible. Your fight against standard C,
your pushing of obsolete standards, your denial of anything
that goes beyond

int main (void)

your refusal to discuss any improvements to the language

is a sure way of killing C. Lucky for the rest of us, the
regulars of clc are not the ones that count anywhere.

--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Aug 4 '08 #47
jacob navia wrote:
Kenny McCormack wrote:
>In article <sl*******************@nospam.invalid>,
Antoninus Twink <no****@nospam.invalidwrote:
>>On 2 Aug 2008 at 20:06, Richard Heathfield wrote:
Bartc said:
Apart the inconvenience and extra space and extra dereferencing,
Right again. There ain't no such thing as a free lunch. Perhaps
there's a better approach that will solve the OP's problem, but I
haven't seen it yet. Any suggestions?
To repeat it yet again: your solution is a C++ solution, not in the
sense that it's written in (C++ but not C), but in the sense that it
fits the approach and mindset of a C++ programmer.

The natural C solution is type-punning by casting structs. You want
to claim that this is not C? Networking is based completely on
manipulating various socket structs etc. in this way. GTK builds a
vast object-oriented framework in C in this way.

And yet, in the twisted minds of the regs, none of those things are
written in C...

They are not written in 'regulars C'
ISO C.
o no network
Berkeley sockets.
o no graphics
OpenGL/X
o no GUI
GTK+/IBM CUA
o no directories
POSIX
o no parallelism
OpenMP
o no threads
pthreads
o no nothing actually :-)
So what are doing here so often?

Aug 4 '08 #48
jacob navia wrote:
Eric Sosman wrote:
<snip>
What I DID say is that people like you are killing the language
making any development impossible.
Remarkable that you can determine the intentions of people over a
newsgroup, from seeing a few posts.
Your fight against standard C,
Er, that's you.
your pushing of obsolete standards,
No one has done this.
your denial of anything that goes beyond

int main (void)
Nonsense. Just examine a month's worth of threads here and you'll find
that all aspects of Standard C (and a little beyond too) are discussed.
your refusal to discuss any improvements to the language
You mean that you are sore that *your* proposals have not met with much
approval here and in c.s.c? Nevertheless they have been discussed a
lot. I can find huge threads on operator overloading, containers,
threads etc.

You're just sore that you did not emerge with the majority consensus.
is a sure way of killing C. Lucky for the rest of us, the
regulars of clc are not the ones that count anywhere.
One would think otherwise from all the hysterical reactions
these "regulars" seem to provoke from you and the trolls.

Aug 4 '08 #49
jacob navia wrote:
Eric Sosman wrote:
>[...]
You're repeating yourself from many earlier threads. You've
told us more than once that C is a dead language,

You are lying, as always
Then I've been misled by my own memory -- and by that of Google,
which quotes you as writing:

"There isn't a single interesting software written in ISO C."

"All people with an interest in language development, software
development are gone."

"C++ is the way, C is dead, go away."

"Why KEEP this OLD interfaces that have proven wrong over
decades? strncpy, gets, asctime, trigraphs, all that CRUFT?"

"The minimal and worst standard of C, ISO C, ..."

"Users of C programs do not need overloading of functions,
agreed. But users of C compilers do, ..."

"All new developments are done in C++, and there is no
way out."

"That is why C99 failed: the compiler writers do not see
any C market since all C programmers should be doing C++."
What I DID say is that people like you are killing the language
making any development impossible. Your fight against standard C,
your pushing of obsolete standards, your denial of anything
that goes beyond

int main (void)

your refusal to discuss any improvements to the language

is a sure way of killing C. Lucky for the rest of us, the
regulars of clc are not the ones that count anywhere.
First, you ascribe to me more power over C than I possess.

Second, if the language is sure to die unless improved --
well, isn't that what I said you said, and you deny saying?

--
Er*********@sun.com
Aug 4 '08 #50

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

Similar topics

21
by: Chris Reedy | last post by:
For everyone - Apologies for the length of this message. If you don't want to look at the long example, you can skip to the end of the message. And for the Python gurus among you, if you can...
699
by: mike420 | last post by:
I think everyone who used Python will agree that its syntax is the best thing going for it. It is very readable and easy for everyone to learn. But, Python does not a have very good macro...
16
by: mike420 | last post by:
Tayss wrote: > > app = wxPySimpleApp() > frame = MainWindow(None, -1, "A window") > frame.Show(True) > app.MainLoop() > Why do you need a macro for that? Why don't you just write
24
by: Bangalore | last post by:
Hi all, I have a problem in accessing elements using overloaded operator . Consider, const int SIZE=10; int FALSE=0; class Array { private: int x; public:
7
by: hierro | last post by:
I have a list of functions (all with suffix T). For each one, I need to implement the following: FunctionT() { if (some_condition) { // do some conversion first FunctionW(); // then do some...
3
by: Stephen Sprunk | last post by:
On a project I'm working on, I ran across the following macros: /* assume s is struct stream *, s->p is char, v is unit16_t or uint32_t */ #define in_uint16_le(s,v) { v = *((s)->p++); v +=...
16
by: Shwetabh | last post by:
Hi, This is a question asked to me in an interview. I haven't been able to figure out an answer for it. Please try to see what can be done about the following problem. /* I have been given two...
47
by: Emil | last post by:
Is there any hope that new versions of PHP will support macros similar to C or C++? I've searched manual and didn't find anything except define directive, but it can be used to define constant...
11
by: San | last post by:
hi there, I am new to c++ and tryig to learn the basics of the c++ concepts. While I was reading the templates, I realize that the templates are a syntax that the compilar expands pased upon the...
33
by: Robert Seacord | last post by:
When writing C99 code is a reasonable recommendation to use inline functions instead of macros? What sort of things is it still reasonable to do using macros? For example, is it reasonable to...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
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,...
0
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...
0
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,...

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.