473,324 Members | 2,356 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,324 software developers and data experts.

Really Weird Conversation

I was posting stuff to a mailing list when a friend, Prof. Corbessero
and I came up with this one. Perhaps you can help resolve this, or add
anything else worth knowing?? Maybe it should be added to the FAQ for
further reference... :)

Ahh. This is my area... C stores arrays in a form called "column
major" order, which actually means the rows come first (don't ask!).
So, here is what a 3x4 array looks like in memory

-------------------------------------------------------------------------
| 0,0 | 0,1 | 0,2 | 0,3 | 1,0 | 1,1 | 1,2 | 1,3 | 2,0 | 2,1 | 2,2 | 2,3 |
-------------------------------------------------------------------------

When you pass an array to a function, all that is really passed is the
address of the first element. With the above layout in mind, as long
as the function knows how long the rows are (ie, the number of
columns) and the size of the base type of the array, it can always
figure out the address of any one element. Since C does not have
bounds checking on arrays, it doesn't need to know the number of rows.
Since it knows the length of each row and the size of each element, it
can "skip" over the rows until it finds the element you are
requesting.
The bounding checks lack is neat. It seems C is the Barry Goldwater of
programming languages. Like like I was saying, passing the array
symbol
(using too much emacs lisp) to 'void foo(char *bar)' means that I have
to
'manually' go thru. I suppose I could use a #define, so the program
knows
where the sections are cut off, if you know what I mean. In the
function
foo, if I were to say 'printf("%s", (bar + 1));' I'd get 'oo'. Head
down
to the right spot in the array, past the null that ends 'Foo', and
I'll
get the next sequence of chars, I printf and get 'Bar'. So in other
words,
using the 'char *bar' style means I have to go thru, as though the
array
was a a strand of sausages, with the pinches being nulls.

if you want position 2,1
the compiler generates an expression to skip over two rows, which
would be
2 (rows) x 4 (things in each row) x W (width in bytes of the base
type)
then the compiler just skips over one more spot to find the 1 column
in that row.
In the general form, for an N dimension array, you need to specify all
the dimensions except the first.

e.g,

double x[3][4]...[n]

should be passed as

void f(double a[][3][4]...[n]) { }
See, when I use that, the pointer is set up so that I can kind of
treat it
like the original array, and not in the 'sausage' fashion above. Try
some
printf's to grok it.


I am not sure what you are asking in part (b). Function calls are not
that expensive.
Depends! If you are doing them again and again, that adds up. A macro
might work, but that is bloat in memory as opposed to CPU strain.
Stuff
that you want to run real fast, either because you have to (boss
said),
you want to (you are doing something like FluxBox), or you want to
look
kewl in front of all the FreeBSD and GNU/Linux users of the fairer sex
(why? duh), might want such an optimisation. Sometimes guddy nuff aint
guddy nuff.
You are not passing the whole array.
See the bit about the sizeof() use. I was aware that it is a pointer.
What
I am asking is: how can I define, within a function, a pointer to a
multidimensional array, that I can treat like a multi-dimensional
array.
If ya don't grok it yet, here are the 'sausage' and 'function' method:

Sausage:

printf("%s", (foo + 1));

Yields 'oo'.

Function:

printf("%s", (foo + 1));

Yields 'Bar'.

printf("%s", ((foo + 1) + 1));

Yields 'ar'. (Actually, my printf syntax in the last bit might be
wrong. I
could nonchalantly d'l an illegal copy of Visual C at this Windoze box
but I don't trespass into people's yards to steal pieces of stinking,
fly-eaten dog
sh*t, so I won't illegally grab a copy of VC which is equivalent
thereto, and I think I'm above theft unlike M$.)

When actually defining an array, you must specify all the dimensions so the compiler
can generate code to allocate the correct amount of memory.


Well, yeah. I kinda figured that'n. :)

--
Top Ten Things Not to Say to a Girl, #3:

"compared to most emacs modes, this keymap you have defined for me
really
bites the bag. perhaps you could make some adjustments and
byte-compile
your e lisp source again? and my hands never got so sticky using
emacs,
why is that? you should try cold booting yourself, that fixes all lisp
problems..."

....and #8:

"STRAITER EMPY IN THE TWENTY-FOURTH-AND-A-HALF CENTURY!!!!"
Nov 13 '05 #1
11 2413
"Mr. Berserker" wrote:

I was posting stuff to a mailing list when a friend, Prof. Corbessero
and I came up with this one. Perhaps you can help resolve this, or add
anything else worth knowing?? Maybe it should be added to the FAQ for
further reference... :)
[...]


I looked and looked, and couldn't find a question
anywhere in your posting. Some technical details, yes.
Some childish drivel, yes. Some snippets from what
must have been a larger explanatory context, yes --
but no question.

The only appropriate answer I can think of is:

--
Er*********@sun.com
Nov 13 '05 #2
Mr. Berserker <El***********@yahoo.com> wrote:
[big snip... I *think* this is the question..]
What I am asking is: how can I define, within a function, a pointer
to a multidimensional array, that I can treat like a
multi-dimensional array.


Given:

int (*foo)[2][3][10];

and:

int bar[15][2][3][10];
int baz[300][2][3][10];

You can set:

foo = bar;

and access bar[a][b][c][d] as foo[a][b][c][d], then set

foo = baz;

and access baz[a][b][c][d] as foo[a][b][c][d].

Is that what you're after?

- Kevin.

Nov 13 '05 #3
Chris Torek <no****@elf.eng.bsdi.com> writes:
In article <84**************************@posting.google.com >
Mr. Berserker <El***********@yahoo.com> wrote:
I was posting stuff to a mailing list when a friend, Prof. Corbessero
and I came up with this one. ... [...]
So, here is what a 3x4 array looks like in memory

-------------------------------------------------------------------------
| 0,0 | 0,1 | 0,2 | 0,3 | 1,0 | 1,1 | 1,2 | 1,3 | 2,0 | 2,1 | 2,2 | 2,3 |
-------------------------------------------------------------------------


This is correct but only visible in strictly conforming code if
you use "unsigned char" pointers to step through all the bytes
making up the array.


So the following program isn't strictly conforming?

#include <stdio.h>

int main(void)
{
int arr[3][3];
int i, j, k;
int *ptr;

for (i = 0; i < 3; i ++) {
for (j = 0; j < 3; j ++) {
arr[i][j] = 10 * j + i;
}
}

ptr = (int*)arr;
for (k = 0; k < 9; k ++) {
printf("ptr[%d] = %2d", k, ptr[k]);
if (k % 3 == 2) printf("\n"); else printf(", ");
}

return 0;
}

On one implementation I tried, it produced the following output:

ptr[0] = 0, ptr[1] = 10, ptr[2] = 20
ptr[3] = 1, ptr[4] = 11, ptr[5] = 21
ptr[6] = 2, ptr[7] = 12, ptr[8] = 22

This of course proves nothing, but given the requirements in the
standard, I find it difficult to imagine a conforming implementation
producing any other output.

The cast of the address of arr to type (int*) is admittedly
suspicious; does it give an implementation enough latitude to do
something non-obvious?

--
Keith Thompson (The_Other_Keith) ks*@cts.com <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 13 '05 #4
In article <ye*************@king.cts.com> Keith Thompson <ks*@cts.com> wrote:
So the following program isn't strictly conforming?

#include <stdio.h>

int main(void)
{
int arr[3][3];
int i, j, k;
int *ptr;

for (i = 0; i < 3; i ++) {
for (j = 0; j < 3; j ++) {
arr[i][j] = 10 * j + i;
}
}

ptr = (int*)arr;
for (k = 0; k < 9; k ++) {
printf("ptr[%d] = %2d", k, ptr[k]);
if (k % 3 == 2) printf("\n"); else printf(", ");
}

return 0;
}


So sayeth the Standards Interpreters over in comp.std.c, yes.
In particular, ptr[3] supposedly could trap.

(Personally, I do not see how one would construct any reasonable
C implementation that traps these, yet allows functions like
memcpy() to exist. It would not bother me in the least if the
Standards Interpreters changed their minds and said this is all
fine. :-) )
--
In-Real-Life: Chris Torek, Wind River Systems (BSD engineering)
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://67.40.109.61/torek/index.html (for the moment)
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 13 '05 #5
Eric Sosman <Er*********@sun.com> wrote in message news:<3F***************@sun.com>...
"Mr. Berserker" wrote:

I was posting stuff to a mailing list when a friend, Prof. Corbessero
and I came up with this one. Perhaps you can help resolve this, or add
anything else worth knowing?? Maybe it should be added to the FAQ for
further reference... :)
[...]


I looked and looked, and couldn't find a question
anywhere in your posting. Some technical details, yes.
Some childish drivel, yes. Some snippets from what
must have been a larger explanatory context, yes --
but no question.

The only appropriate answer I can think of is:


As per usual, someone on USENET has an attitude, which, if turds were
as big as it, would result in bog paper the size of the Bayeux
Tapestry, and bog rolls that are actually converted cement mixer
drums.
Nov 13 '05 #6
Kevin Easton <kevin@-nospam-pcug.org.au> wrote in message news:<ne********************@tomato.pcug.org.au>.. .
Mr. Berserker <El***********@yahoo.com> wrote:
[big snip... I *think* this is the question..]
What I am asking is: how can I define, within a function, a pointer
to a multidimensional array, that I can treat like a
multi-dimensional array.
Given:

int (*foo)[2][3][10];

and:

int bar[15][2][3][10];
int baz[300][2][3][10];

You can set:

foo = bar;

and access bar[a][b][c][d] as foo[a][b][c][d], then set

foo = baz;

and access baz[a][b][c][d] as foo[a][b][c][d].

Is that what you're after?


I thought that was only good for moving thru whole arrays; didn't
something to that turn up in the C FAQ? Well, I'll fire up emacs and
gcc once I get home and see how it goes... Thx for the advice! :)

- Kevin.

Nov 13 '05 #7
Chris Torek <no****@elf.eng.bsdi.com> writes:
In article <ye*************@king.cts.com> Keith Thompson <ks*@cts.com> wrote:
So the following program isn't strictly conforming?
[snip]
So sayeth the Standards Interpreters over in comp.std.c, yes.
In particular, ptr[3] supposedly could trap.

(Personally, I do not see how one would construct any reasonable
C implementation that traps these, yet allows functions like
memcpy() to exist. It would not bother me in the least if the
Standards Interpreters changed their minds and said this is all
fine. :-) )


I wonder how even an unreasonable C implementation could break this
while still conforming to the standard. Hmm. I suppose it could
store bounds information in pointers, and propagate the bounds of the
first row of arr to ptr on the assignment.

I wonder how the DS-9000 handles this.

--
Keith Thompson (The_Other_Keith) ks*@cts.com <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 13 '05 #8

On Thu, 24 Jul 2003, Chris Torek wrote:

Keith Thompson <ks*@cts.com> wrote:

So the following program isn't strictly conforming? <trim> int arr[3][3];
int *ptr;
ptr = (int*)arr;
for (k = 0; k < 9; k ++) {
printf("ptr[%d] = %2d", k, ptr[k]);


So sayeth the Standards Interpreters over in comp.std.c, yes.
In particular, ptr[3] supposedly could trap.

(Personally, I do not see how one would construct any reasonable
C implementation that traps these, yet allows functions like
memcpy() to exist. It would not bother me in the least if the
Standards Interpreters changed their minds and said this is all
fine. :-) )


I could conceive of a bounds-checking implementation that had no
bounds checking on pointers to void. On such an implementation
with optimization turned off, the clever-newbie workaround would
be

int *ptr = (void*)arr; /* cast to int* w/o bounds checking */

but since AFAIK no implementation actually does this, c.l.c is
saved from having to explain why the above is silly in the extreme.

:)
-Arthur
Nov 13 '05 #9
Chris Torek <no****@elf.eng.bsdi.com> wrote in message news:<bf**********@elf.eng.bsdi.com>...
In article <84**************************@posting.google.com >
Mr. Berserker <El***********@yahoo.com> wrote:
I was posting stuff to a mailing list when a friend, Prof. Corbessero
and I came up with this one. ...
Ahh. This is my area... C stores arrays in a form called "column
major" order, which actually means the rows come first (don't ask!).
You do not say who wrote this, but it is quite wrong.

Fortran uses column-major order; C uses row-major order.
So, here is what a 3x4 array looks like in memory

-------------------------------------------------------------------------
| 0,0 | 0,1 | 0,2 | 0,3 | 1,0 | 1,1 | 1,2 | 1,3 | 2,0 | 2,1 | 2,2 | 2,3 |
-------------------------------------------------------------------------


This is correct but only visible in strictly conforming code if
you use "unsigned char" pointers to step through all the bytes
making up the array.
The bounding checks lack is neat.


C compilers are allowed to do bounds-checking, and some do.


Hm, you are BSD I see? Wind Rivers, aren't they embedded developers of
BSD? Don't most BSD'ers user gcc? I am using gcc right now. Since I
don't use non-free softwares including angband and xfig, gcc is all I
really concern myself with. Last time I checked gcc, doesn't do bounds
checking. I'd need to check again...
Nov 13 '05 #10
Chris Torek <no****@elf.eng.bsdi.com> wrote in message news:<bf**********@elf.eng.bsdi.com>...
In article <84**************************@posting.google.com >
Mr. Berserker <El***********@yahoo.com> wrote:
I was posting stuff to a mailing list when a friend, Prof. Corbessero
and I came up with this one. ...
Ahh. This is my area... C stores arrays in a form called "column
major" order, which actually means the rows come first (don't ask!).
You do not say who wrote this, but it is quite wrong.

Fortran uses column-major order; C uses row-major order.
So, here is what a 3x4 array looks like in memory

-------------------------------------------------------------------------
| 0,0 | 0,1 | 0,2 | 0,3 | 1,0 | 1,1 | 1,2 | 1,3 | 2,0 | 2,1 | 2,2 | 2,3 |
-------------------------------------------------------------------------


This is correct but only visible in strictly conforming code if
you use "unsigned char" pointers to step through all the bytes
making up the array.


Woops, forgot to ask this: what is the difference between signed and
unsigned char *? Is it just good programming practise? (Unless your
architecture has negative address space...)
Nov 13 '05 #11
In article <84**************************@posting.google.com >
Mr. Berserker <El***********@yahoo.com> writes:
Hm, you are BSD I see? Wind Rivers, aren't they embedded developers of
BSD? Don't most BSD'ers user gcc?
Wind River do sell an embedded BSD, and all the BSDs (there are
many, and even MacOS X can be considered a "BSD" in various ways)
do currently use gcc. We also sell the Diab compilers, which I
have not worked on myself.
... Last time I checked gcc, doesn't do bounds
checking. I'd need to check again...


Google search for "bounds checking" "gcc" turned up quite a few
links, including:

<http://gcc.gnu.org/projects/bp/main.html>
<http://www.doc.ic.ac.uk/~phjk/BoundsChecking.html>
<http://web.inter.nl.net/hcc/Haj.Ten.Brugge/>

The last of these claims to support gcc 3.x.
--
In-Real-Life: Chris Torek, Wind River Systems (BSD engineering)
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://67.40.109.61/torek/index.html (for the moment)
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 13 '05 #12

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

Similar topics

2
by: quadric | last post by:
Hi, I have an application that requires that Python initiate and mediate a live and iterative conversation between an external application (in which Python is embedded) and an external Excel...
761
by: Neo-LISPer | last post by:
Hey Recently, I researched using C++ for game programming and here is what I found: C++ game developers spend a lot of their time debugging corrupted memory. Few, if any, compilers offer...
9
by: ZorpiedoMan | last post by:
This is so weird, and I cannot even isolate the cause enough to give any clues as to how to reproduce the error, so this is probably a real shot in the dark... BUT, has anyone ever run into a...
7
by: JJ | last post by:
Dear all, I have this weird problem on the website I maintain.... A few visitors seemed to be unable to XS the website. It has a front image, with a link underneeth it saying: click here to...
131
by: pemo | last post by:
Is C really portable? And, apologies, but this is possibly a little OT? In c.l.c we often see 'not portable' comments, but I wonder just how portable C apps really are. I don't write...
3
by: MS News | last post by:
hi I need help.I want to to record my Skype Messenger Conversation i.e Incoming and Outgoing conversation in C#.Please if some body know guide me.I need starting help.what should i study for...
18
by: atv | last post by:
at least to me it is. I can't figure out for the life what it is i'm doing wrong here. i have a function called assign_coordinate. usually, i pass a malloced pointer to it, then individual...
0
by: P Pulkkinen | last post by:
Dear all, sorry, i know this code is far little too long to debug here, but there is really annoying logical error. If someone debugs this, I really offer warm virtual handshake. What this...
56
by: tasteless | last post by:
Hi guys, I need really hard questions (about 10) about PHP programming (some of elements OOP as well, but no MySQL questions - this is different part), this questions needs to be very hard, but...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you

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.