struct problems

B

Bill Cunningham

I've been having problems with structs for awhile now. I've tried
everything this is the latest errors from Bash's stdout and the source I've
tried. Am I getting something backwards here?

#include <stdio.h>

struct cat {
char *name;
char *color;};

struct cat kitty1,kitty2;

kitty1={"striper","striped"};
kitty2={"spook","black"};

main() {
printf("%s %s\n",kitty1.name,kitty2.name);}

----
p.c:9: error: conflicting types for 'kitty1'
p.c:7: error: previous declaration of 'kitty1' was here
p.c:9: warning: initialization makes integer from pointer without a cast
p.c:9: warning: excess elements in scalar initializer
p.c:9: warning: (near initialization for `kitty1')
p.c:9: warning: data definition has no type or storage class
p.c:10: error: conflicting types for 'kitty2'
p.c:7: error: previous declaration of 'kitty2' was here
p.c:10: warning: initialization makes integer from pointer without a cast
p.c:10: warning: excess elements in scalar initializer
p.c:10: warning: (near initialization for `kitty2')
p.c:10: warning: data definition has no type or storage class
p.c: In function `main':
p.c:13: error: request for member `name' in something not a structure or
union
p.c:13: error: request for member `name' in something not a structure or
union


Bill
 
R

Richard Tobin

Bill Cunningham said:
#include <stdio.h>

struct cat {
char *name;
char *color;};

struct cat kitty1,kitty2;

kitty1={"striper","striped"};
kitty2={"spook","black"};

You can't do assignments outside of a function.

Perhaps you meant to initialise the variables instead?

struct cat kitty1={"striper","striped"};
struct cat kitty2={"spook","black"};

Or perhaps you meant to do the assignment inside a function, in which
case:

- if you're using C90 there is no way to write literal struct values,
or
- if you're using C99 the syntax for "compound literals" would be

kitty1 = (struct cat){"striper","striped"};

-- Richard
 
P

Peter Nilsson

Should probably make these const char *.
You can't do assignments outside of a function.

Perhaps you meant to initialise the variables instead?

struct cat kitty1={"striper","striped"};
struct cat kitty2={"spook","black"};

Or perhaps you meant to do the assignment inside a function,
in which case:

 - if you're using C90 there is no way to write literal
struct values,

True, but that hasn't stopped C90 users...

void f(void)
{
static const struct cat striper = { "striper", "striped"};
static const struct cat spook = { "spook", "black"};
kitty1 = striper;
kitty2 = spook;
}
 
M

Mark Wooding

Bill Cunningham said:
I've been having problems with structs for awhile now. I've tried
everything this is the latest errors from Bash's stdout and the source I've
tried. Am I getting something backwards here?

#include <stdio.h>

struct cat {
char *name;
char *color;};

Dull style thing. In C, people almost universally put close braces on
their own lines, at least if they can't fit the close brace on the same
line as the open one.

struct cat {
char *name;
char *colour;
};
struct cat kitty1,kitty2;

kitty1={"striper","striped"};
kitty2={"spook","black"};

And this is the actual problem. You're presumably trying to initialize
these structure variables. You want

struct cat
kitty1 = { "striper", "striped" },
kitty2 = { "spook", "black" };

The compiler is complains:
p.c:9: error: conflicting types for 'kitty1'
p.c:7: error: previous declaration of 'kitty1' was here
p.c:9: warning: initialization makes integer from pointer without a cast
p.c:9: warning: excess elements in scalar initializer
p.c:9: warning: (near initialization for `kitty1')

Why? Well, a declaration `VAR = ...' at top level used implicitly to
tell the compiler that VAR was an `int'. So
kitty1={"striper","striped"};

says: make a global variable (technically, static storage duration,
external linkage) with type `int', and call it `kitty1'. The compiler
says `err... but you already said ``kitty1'' was a struct cat: I'm all
confused now.' It then goes on to say that `{"striper","striped"}'
isn't a sensible thing to initialize an integer with.

So to fix it, you need to repeat that your kitties are `struct cat's.
But at that point the original declaration becomes completely redundant
so you can delete it. Giving the code I wrote above.
main() {
printf("%s %s\n",kitty1.name,kitty2.name);}

You're not allowed to leave off the `int' any more, and main is meant to
return an integer -- zero will do to indicate successful completion.
So:

int main()
{ printf("%s %s\n", kitty1.name, kitty2.name); return 0; }

-- [mdw]
 
K

Keith Thompson

Bill Cunningham said:
I've been having problems with structs for awhile now. I've tried
everything this is the latest errors from Bash's stdout and the source I've
tried. Am I getting something backwards here?

#include <stdio.h>

struct cat {
char *name;
char *color;};

Bunching up multiple closing braces and semicolons at the end of a
line like this makes your code difficult to read, and the one-column
indentation doesn't help. For a while, I think you were running your
code through "indent". I suggest you resume doing so.
struct cat kitty1,kitty2;

kitty1={"striper","striped"};
kitty2={"spook","black"};

These are not valid expressions of type "struct cat". They're valid
initializers -- i.e., you could have written:

struct cat kitty1 = {"striper", "striped"};

but you can't use them in an assignment.

C99 provides "compound literals", but pre-C99 compilers might not
support them. You can always assign to each member individually:

kitty1.name = "striper";
kitty1.color = "striped";

(You should realize, of course, that these are pointer assignments,
not array assignments.)

This should be "int main(void)". You've been told this a gazillion
times.

[snip]
 
K

Keith Thompson

Mark Wooding said:
And this is the actual problem. You're presumably trying to initialize
these structure variables. You want

struct cat
kitty1 = { "striper", "striped" },
kitty2 = { "spook", "black" };

As a matter of style, I wouldn't declare multiple objects in a single
line line that. I'd write:

struct cat kitty1 = { "striper", "striped" };
struct cat kitty2 = { "spook", "black" };

[...]
 
R

Richard

Keith Thompson said:
Mark Wooding said:
And this is the actual problem. You're presumably trying to initialize
these structure variables. You want

struct cat
kitty1 = { "striper", "striped" },
kitty2 = { "spook", "black" };

As a matter of style, I wouldn't declare multiple objects in a single
line line that. I'd write:

struct cat kitty1 = { "striper", "striped" };
struct cat kitty2 = { "spook", "black" };

[...]

His style is far nicer IMO. Why specify the type twice?
Localisation. Compact. Clean.
 
B

Bill Cunningham

(e-mail address removed) (Richard Tobin) wrote:

[snip]
or
- if you're using C99 the syntax for "compound literals" would be

kitty1 = (struct cat){"striper","striped"};

Is this a cast to type struct?

Bill
 
B

Bill Cunningham

You can't do assignments outside of a function.

Perhaps you meant to initialise the variables instead?

Yes. That's what I thought I was doing when I wrote:

struct cat kitty1,kitty2;
struct cat kitty1={"striper","striped"};
struct cat kitty2={"spook","black"};

Or perhaps you meant to do the assignment inside a function, in which
case:

- if you're using C90 there is no way to write literal struct values,
or
- if you're using C99 the syntax for "compound literals" would be

kitty1 = (struct cat){"striper","striped"};

I didn't know that the assignments couldn't be done outside of a
function.

Bill
 
K

Keith Thompson

Bill Cunningham said:
(e-mail address removed) (Richard Tobin) wrote:

[snip]
or
- if you're using C99 the syntax for "compound literals" would be

kitty1 = (struct cat){"striper","striped"};

Is this a cast to type struct?

No, it's a compound literal.

A cast must take a valid expression as its argument. Since
{"striper","striped"} wasn't a valid expression without the preceding
(struct cat), it isn't a valid expression by itself even with the
preceding (struct cat).

A C99 compound literal uses a syntax that's similar to the syntax for
a cast expression (something preceded by a type name in parentheses),
but it's not a cast expression; it's a distinct kind of expression.

See C99 6.5.2.5.
 
K

Keith Thompson

Bill Cunningham said:
I didn't know that the assignments couldn't be done outside of a
function.

An assignment (when followed by a semicolon) is a statement, and
statements can occur only inside functions.

If a statement were allowed outside a function, when would it
be executed? (That's a trick question; the fact that there's no
good answer is why statements outside functions are disallowed.)
 
B

Bill Cunningham

Bunching up multiple closing braces and semicolons at the end of a
line like this makes your code difficult to read, and the one-column
indentation doesn't help. For a while, I think you were running your
code through "indent". I suggest you resume doing so.

I usually do. But since this was such a small amount of code I thought
it readable. I wrote this several times and then got lazy. My first atempt
was:

struct cat
{
char *name;
char *color;
};


Bill
 
B

Bill Cunningham

This new document seems to compile fine. And work fine.

#include <stdio.h>

struct cat
{
char *name;
char *color;
};

int main(void)
{
struct cat striper = { "striper", "striped" };
struct cat spook = { "spook", "black" };
printf("%s %s\n", striper.name, spook.name);
printf("%s %s\n", striper.color,spook.color);
return 0;
}

So what have I learned? struct initialization needs to be inside a function.

Now am I ready for singley linked lists ? (Rhetorical)
This is going to involve pointers to structs and the -> operator.

Bill
 
B

Ben Bacarisse

Bill Cunningham said:
This new document seems to compile fine. And work fine.

#include <stdio.h>

struct cat
{
char *name;
char *color;
};

int main(void)
{
struct cat striper = { "striper", "striped" };
struct cat spook = { "spook", "black" };
printf("%s %s\n", striper.name, spook.name);
printf("%s %s\n", striper.color,spook.color);
return 0;
}

So what have I learned? struct initialization needs to be inside a
function.

You should not have learned that. You did find out that assignment
must be done inside a function but at least two posters suggested you
solve the problem you created by trying to assign outside of function
by using an initialisation instead. This which means that
initialisation *is* permitted outside of all functions.

Not that you *should* do this. Local variable are to be preferred in
almost all cases.
Now am I ready for singley linked lists ? (Rhetorical)
This is going to involve pointers to structs and the -> operator.

I'd start by writing a function that uses malloc to create and return a
struct cat. Then try to write a function that can print a struct cat
when it is passed a pointer to one. In other words, complete the
following program:

int main(void)
{
struct cat *catptr = new_cat("buzz", "hairless");
print_cat(catptr);
free(catptr);
}

It helps to get pointers straight before you tackle lists or trees.
 
R

Richard

Keith Thompson said:
An assignment (when followed by a semicolon) is a statement, and
statements can occur only inside functions.

So you are saying a line like

int bill = 1;

is NOT legal outside a function?

....
 
G

Guest

An assignment (when followed by a semicolon) is a statement, and
statements can occur only inside functions.

If a statement were allowed outside a function, when would it
be executed?  (That's a trick question; the fact that there's no
good answer is why statements outside functions are disallowed.)

Pascal had a good answer.
 
G

Guest

Keith Thompson said:
[...]
    I didn't know that the assignments couldn't be done outside of a
function.
An assignment (when followed by a semicolon) is a statement, and
statements can occur only inside functions.
So you are saying a line like
int bill = 1;
is NOT legal outside a function?

no. but then it isn't a statement

that of course should have read
"yes. But then it isn't a statement"

hey! I was within an order of magnitude of the correct answer!
That used in work in physics assignments...
 

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,955
Messages
2,570,117
Members
46,705
Latest member
v_darius

Latest Threads

Top