Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Re: What have we done wrong in this code sample please

Reply
Thread Tools

Re: What have we done wrong in this code sample please

 
 
Claire
Guest
Posts: n/a
 
      06-25-2003

> You have given us incomplete and non-standard code - present a minimal but
> compilable code fragment using no non-standard extensions that
> demonstrates the problem, and we may be able to help.
> --
> Freenet distribution not available


Sorry about that fellas, how's the stripped following as an alternative?
I guess Im stuck on how to pass the PRecipe record pointer field to my
TestFunc properly.
Can you help please. Ive still not got it right.


typedef struct
{
// all other fields removed
char pszStartStr[6][21];// An array of 6 strings, each one 20 chars plus
terminating character
}TRecipe;
typedef TRecipe *PRecipe;


char *s1[2] = {"s1_0","s1_1"};
char *s2[2][2]={"s2_00","s2_01","s2_10","s2_11"};

bool PlaceText(char nRow, char nColumn, char *pszText)// writes string to
display
{
//foobar;
return 1;
}

void TestFunc(char **Str)
{
PlaceText(1,1,(char*)Str[0]);// 1st item in list of strings
PlaceText(2,1,(char*)Str[1]);// 2nd item in list of strings
}

void main(void)
{
PRecipe pRecipe;
TRecipe Recipe;

pRecipe = &Recipe;// Temporary test variable

strcpy(Recipe.pszStartStr[0], "Hello");
strcpy(Recipe.pszStartStr[1], "Goodbye");

TestFunc(s1); // this one works
TestFunc(s2[0]); // this one works

//TestFunc(pRecipe->pszStartStr[0]);
//TestFunc(&pRecipe->pszStartStr[0]);
//TestFunc((char**)(pRecipe->pszStartStr[0]));
// All 3 of the above are abysmal attempts to pass an arrayed string field
from a record pointer and none work
}


 
Reply With Quote
 
 
 
 
Arthur J. O'Dwyer
Guest
Posts: n/a
 
      06-25-2003

On Wed, 25 Jun 2003, Claire wrote:
>
> Sorry about that fellas, how's the stripped following as an alternative?
> I guess Im stuck on how to pass the PRecipe record pointer field to my
> TestFunc properly.
> Can you help please. Ive still not got it right.
>
> typedef struct
> {
> char pszStartStr[6][21];
> }TRecipe;
> typedef TRecipe *PRecipe;


Note that I've stripped all of your C99-style comments.
Not only will they keep your code from compiling on any
popular compiler in conforming mode, but they were supremely
dumb comments in the first place. We can *see* how many
characters are in array pszStartStr[0] -- we don't need
a comment to tell us that!

>
> char *s1[2] = {"s1_0","s1_1"};
> char *s2[2][2]={"s2_00","s2_01","s2_10","s2_11"};
>
> void TestFunc(char **Str)
> {
> PlaceText(1,1,(char*)Str[0]);
> PlaceText(2,1,(char*)Str[1]);


Both casts to (char *) are useless. Think about it -- if Str is
a pointer to pointer to char, then what's Str[0]? It's a pointer
to char. The cast buys you nothing except extra typing and code
clutter.

> }
>
> void main(void)


int main(void)

> {
> PRecipe pRecipe;
> TRecipe Recipe;
>
> pRecipe = &Recipe;
>
> strcpy(Recipe.pszStartStr[0], "Hello");
> strcpy(Recipe.pszStartStr[1], "Goodbye");
>
> TestFunc(s1); // this one works
> TestFunc(s2[0]); // this one works
>
> //TestFunc(pRecipe->pszStartStr[0]);


pRecipe->pszStartStr[0] is an array[21] of char; decays to (char *).

> //TestFunc(&pRecipe->pszStartStr[0]);


&pRecipe->pszStartStr[0] is a pointer to array[21] of char.

> //TestFunc((char**)(pRecipe->pszStartStr[0]));


pRecipe->pszStartStr[0] decays to (char *),
and then you cast it to (char **). That will never work.
Casting in ignorance doesn't solve anything.

> // All 3 of the above are abysmal attempts to pass an arrayed string field
> from a record pointer and none work


*That* was a somewhat useful comment!


char *temp = pszStartStr[0];
TestFunc(&temp);

/* &temp is a pointer to a pointer to char */

Anyway, it would be simpler just to re-write your TestFunc()
code so that it takes two (char *) arguments, or re-write your
data structures so they contain arrays of (char *), rather than
arrays of (char[21]).

return 0;
> }


HTH
-Arthur
 
Reply With Quote
 
 
 
 
Claire
Guest
Posts: n/a
 
      06-25-2003
Many thanks for giving me your time Arthur

> Note that I've stripped all of your C99-style comments.
> Not only will they keep your code from compiling on any
> popular compiler in conforming mode, but they were supremely
> dumb comments in the first place. We can *see* how many
> characters are in array pszStartStr[0] -- we don't need
> a comment to tell us that!


As a newby, I assume you mean /**/ is the standard. Sorry about that, we
turn // on asap on our compiler options.
Re "dumb" comments. "You" will fully understand, as you are clearly an
expert at this, but do you know if "I" understand?
I comment to show how Im thinking, not to explain to you. If I were
mentoring I'd find it valuable to see my students thought processes written
down.

> > void TestFunc(char **Str)
> > {
> > PlaceText(1,1,(char*)Str[0]);
> > PlaceText(2,1,(char*)Str[1]);

>
> Both casts to (char *) are useless. Think about it -- if Str is
> a pointer to pointer to char, then what's Str[0]? It's a pointer
> to char. The cast buys you nothing except extra typing and code
> clutter.

Yes, sorry, I appreciate that. Ive been testing it within our project that
has overrides to the common variable types and forgot to remove the casts.

>
> char *temp = pszStartStr[0];
> TestFunc(&temp);
>
> /* &temp is a pointer to a pointer to char */
>
> Anyway, it would be simpler just to re-write your TestFunc()
> code so that it takes two (char *) arguments, or re-write your
> data structures so they contain arrays of (char *), rather than
> arrays of (char[21]).

Yes it would be simpler, but that is a test function. I produced some
simpler code in answer to an earlier responders comment that they couldnt
follow the original.
My actual function prototype is
void MessageDlg(U8 nKeyMask, const U8 *pszTitle, const U8 **Items, U8
numItems);
Where nKeyMask is a mask of the key strokes accepted to close the dialog
pszTitle is title of the dialog box
Items is a pointer to an array/list of strings/char*
numItems is the number of items in the array.

Our records are large arrays of structs that are assigned permanent noinit
space in battery backed ram. We have no heap or dynamic allocation.

Please. Why is it not possible to pass the correct parameter directly rather
than copying to another variable then passing that one?


Claire


 
Reply With Quote
 
Mark McIntyre
Guest
Posts: n/a
 
      06-25-2003
On Wed, 25 Jun 2003 16:48:16 +0100, in comp.lang.c , "Claire"
<> wrote:

>Re "dumb" comments. "You" will fully understand, as you are clearly an
>expert at this, but do you know if "I" understand?


this is a fair point. However its generally felt that in production
code, comments ar there for *other people*, to explain to them what
your code is doing. Comments should only exist for parts that are
tricky.

pointless comment:
int foo; // declare variable foo of type int

more useful comments
FOO foo; //FOO is typdef'ed in header potato.h

// must do integer maths here, to ensure x is rounded properly
x = (int)y/456 + (intt)z/45;

--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>


----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
 
Reply With Quote
 
Chris Torek
Guest
Posts: n/a
 
      06-26-2003
(I wound up snipping all the code. Sorry about that.)

In article <bdcg1q$gm3$>
Claire <> writes:
>My actual function prototype is
>void MessageDlg(U8 nKeyMask, const U8 *pszTitle, const U8 **Items, U8
>numItems);
>Where nKeyMask is a mask of the key strokes accepted to close the dialog
>pszTitle is title of the dialog box
>Items is a pointer to an array/list of strings/char*
>numItems is the number of items in the array.


You are using "U8" instead of "char *" (e.g., for pszTitle), but
compiler-generated strings have type "array of char". This forces
you to use casts.

Casts are bad news. If your code were to compile cleanly (no
errors, no warnings, etc.) when cast-free, it would have a
significantly higher chance of working. Of course, as I think you
already found, simply changing "U8" to "char" does not make the
code compile cleanly.

The reason is that you have confused arrays, which can become
pointer values under particular circumstances, with pointers.
Although array objects do sometimes produce pointer values, array
objects are not themselves pointers.

>Please. Why is it not possible to pass the correct parameter directly rather
>than copying to another variable then passing that one?


See <http://67.40.109.61/torek/c/pa.html>. When you have an array
named A of size N and element-type T, and pass &A to some other
function, you get a pointer value of type "pointer to array N of
T" that points to the entire array. If you pass "the value" of A,
or use &A[0], you get a value of type "pointer to T" that points
to the first element of the array A.

>Our records are large arrays of structs that are assigned permanent noinit
>space in battery backed ram. We have no heap or dynamic allocation.


Such memory is usually a (relatively) scarce resource, so you might
want to encode things tightly in this space, and expand them out for
"regular" use in ordinary (non-backed-up) RAM. This sort of thing
is probably more an issue for comp.arch.embedded, though.
--
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.
 
Reply With Quote
 
Bernardo Signori
Guest
Posts: n/a
 
      06-26-2003
"Claire" <> wrote in message news:<bdc7cd$bl9$>...
> void TestFunc(char **Str)
> {
> PlaceText(1,1,(char*)Str[0]);// 1st item in list of strings
> PlaceText(2,1,(char*)Str[1]);// 2nd item in list of strings
> }


declare TestFunc as
void TestFunc(char (*Str)[21])

Then you can call this function as you would expect:
TestFunc(pRecipe->pszStartStr);

Of course the tests you wrote with s1_0, s2_00, etc. are no longer
valid, because it is not the same a pointer to an array of 21 chars
than another pointer to an array with a different size.

Bernardo
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
What Have I Done Wrong? Thom Computer Support 14 08-01-2007 02:01 PM
What have I done wrong ?... Bigbazza Computer Support 4 08-04-2006 02:11 AM
I asked before and was told it could not be done, well its Done...?? Karen Parker NZ Computing 32 08-27-2004 07:21 AM
New programmer - please help - what have I done wrong Johnny Java 3 03-07-2004 10:19 PM
What have I done wrong? RM Digital Photography 15 12-04-2003 02:52 PM



Advertisments