struct and multiple indirection for a variable

B

Brian Stubblefield

Dear group,

I am a beginner to C.

Below is a segment of a program that I am trying to debug:

#include <stdio.h>
#include <signal.h>
/*#include <stdlib.h>*/
#define BIT char

int main(void)
{
/* editted code */

void *p;

char rec1_io[81] = {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '
', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '
', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '
', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '
', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '
', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '
', ' '};

p = &(rec1_io);

struct RECIN1 {
char pgm[10];
char rec_type[2];
char filler[4];
char form[6];
char filler1[59];
} **recin1_struct =&p;

/* editted code */

When I compile this code, I received the following error message
pertaining to the struct statement:

warning: initialization from incompatible pointer type

Can somebody please recommend a better way that the above code can be
accomplished or fixed?

Thank you in advance,

Brian
 
A

Arthur J. O'Dwyer

I *strongly* recommend you use 'unsigned char' for anything even
remotely resembling bitwise operations. While it is possible to use
signed types with bitwise operations, it's also possible to juggle
chainsaws. I don't do either one, generally speaking.

Icky hard tabs. Don't use tabs on Usenet; they don't survive the
ASCIIfication. Google 'detab'.
char rec1_io[81] = {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '
^^ this 81 is implicit in the length of the contant.

Actually, the "constant" is a syntax error: you can't put a literal
newline inside single quotes like that. Assuming the OP meant to
initialize the array to 81 blank spaces, he could have written either
the above --- properly line-broken --- or else

char rec1_io[81] = " "
" ";

or, far more readably,

char rec1_io[81];
memset(rec1_io, ' ', sizeof rec1_io);

Brackets not needed.

Nit FYI: the canonical names are (parentheses), [brackets], {braces},
and said:
struct RECIN1 {
char pgm[10];
char rec_type[2];
char filler[4];
char form[6];
char filler1[59];
} **recin1_struct =&p;

&p is of type char**,

s/char**/void**/
while recin1_struct is of type struct RECIN1 **,
you need to cast by doing this:

No, casting is precisely the wrong thing in this situation (as in
every situation except one that I can think of, and that's nothing to
worry a newbie). NEVER CAST ANYTHING IN C!
In this case, casting is wrong because it hides undefined behavior.
What the OP apparently means to do is initialize every field of his
structure to all-blanks; Lord knows why --- he's probably confused
about the role of the terminating null character in C-style strings.
But for the sake of argument, let's assume he really wants to do
this. Then one correct approach would be

#include <string.h>
[...]

struct RECIN1 dummy, *dummy2 = &dummy;
struct RECIN1 **recin1_struct = &dummy2;

memset(&dummy.pgm, ' ', sizeof dummy.pgm);
memset(&dummy.rec_type, ' ', sizeof dummy.rec_type);
memset(&dummy.filler, ' ', sizeof dummy.filler);
memset(&dummy.form, ' ', sizeof dummy.form);
memset(&dummy.filler1, ' ', sizeof dummy.filler1);

Now you have a properly initialized structure (named 'dummy'),
a nice readable initialization procedure (which could be made into
its own function if desired), and no warnings or errors --- by
*design*, not by accident.
This is a warning, and is not fatal.

Do not spout malicious garbage, please. Plain garbage is at
least sometimes funny, but if you *know* there's a major flaw in
the code, you should not imply that it's "only a warning." Bugs
is bugs, by and large, and this one was glaringly big.

I do believe this is a classic example of the "How do I insert
this bullet into my foot?" newbie-question. We'll gladly tell you
how to purchase the gun and shoot yourself in the foot with it,
but it always turns out to be the case that you really wanted to
shoot a gopher and your foot was in the way. If you had just asked
how to kill a gopher in the first place, you would have received
much more helpful answers.

-Arthur
 
B

Barry Schwarz

Brian said:
Dear group,

I am a beginner to C.

Below is a segment of a program that I am trying to debug:

#include <stdio.h>
#include <signal.h>
/*#include <stdlib.h>*/
#define BIT char

int main(void)
{
/* editted code */

void *p;

char rec1_io[81] = {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '
^^ this 81 is implicit in the length of the contant.
', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '
', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '
', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '
', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '
', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '
', ' '};

p = &(rec1_io); Brackets not needed.

struct RECIN1 {
char pgm[10];
char rec_type[2];
char filler[4];
char form[6];
char filler1[59];
} **recin1_struct =&p;

&p is of type char**, while recin1_struct is of type struct RECIN1 **,
you need to cast by doing this:

&p is of type void**.
**recin1_struct = (struct RECIN1 **)&p;

Syntactically the way to avoid the compiler diagnostic but
operationally valid only

if the alignment of rec1_io is compatible with that of a struct
RECIN1
and if the size and format of a struct RECIN1* is the same as a
void*
This is a warning, and is not fatal.



<<Remove the del for email>>
 
M

Martin Johansen

Brian said:
Dear group,

I am a beginner to C.

Below is a segment of a program that I am trying to debug:

#include <stdio.h>
#include <signal.h>
/*#include <stdlib.h>*/
#define BIT char

int main(void)
{
/* editted code */

void *p;

char rec1_io[81] = {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '
^^ this 81 is implicit in the length of the contant.
', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '
', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '
', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '
', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '
', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '
', ' '};

p = &(rec1_io); Brackets not needed.

struct RECIN1 {
char pgm[10];
char rec_type[2];
char filler[4];
char form[6];
char filler1[59];
} **recin1_struct =&p;

&p is of type char**, while recin1_struct is of type struct RECIN1 **,
you need to cast by doing this:

**recin1_struct = (struct RECIN1 **)&p;
/* editted code */

When I compile this code, I received the following error message
pertaining to the struct statement:

warning: initialization from incompatible pointer type

This is a warning, and is not fatal.
 
B

Brian Stubblefield

Thank you for your suggestions. I have implemented them and the
compile issues have gone away.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top