syntax errror

D

danu

I have a structure :

typedef struct{
char magicNum[2];
int width;
int height;
int maxGrey;
int pixels[ROW][COLUMN];
} ImageT;

When I try to code this statement:

fscanf(infile, "%c", ImageT.magicNum[0]);

there is an error messege saying:

error: syntax error before 'ImageT'

What's the reason for that? What am I doing wrong here?
thanks.
 
B

Ben Pfaff

danu said:
typedef struct{
char magicNum[2];
int width;
int height;
int maxGrey;
int pixels[ROW][COLUMN];
} ImageT;

When I try to code this statement:

fscanf(infile, "%c", ImageT.magicNum[0]);

there is an error messege saying:

error: syntax error before 'ImageT'

You defined a structure type and gave it a typedef name ImageT.
You didn't define any object of type ImageT.
The . operator works on objects, not on types.
 
K

Kenneth Brody

danu said:
I have a structure :

typedef struct{
char magicNum[2];
int width;
int height;
int maxGrey;
int pixels[ROW][COLUMN];
} ImageT;

When I try to code this statement:

fscanf(infile, "%c", ImageT.magicNum[0]);

there is an error messege saying:

error: syntax error before 'ImageT'

What's the reason for that? What am I doing wrong here?
thanks.

Because ImageT is a type, not a variable.

You would need to declare a variable of type "ImageT", such as:

ImageT MyImage;

and then:

fscanf(infile, "%c", &MyImage.magicNum[0]);

(Note that "&" to pass the address of the char.)

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:[email protected]>
 
K

Keith Thompson

danu said:
I have a structure :

typedef struct{
char magicNum[2];
int width;
int height;
int maxGrey;
int pixels[ROW][COLUMN];
} ImageT;

You have a structure type called "ImageT". You don't have an object
(variable) of that type.
When I try to code this statement:

fscanf(infile, "%c", ImageT.magicNum[0]);

there is an error messege saying:

error: syntax error before 'ImageT'

What's the reason for that? What am I doing wrong here?

The problem is that you're trying to use ImageT as if it were a
variable name. It's like trying to say

x = int + 1;

It would be nice if the compiler could give you a clearer error
message. The reasons it doesn't are obscure ones having to do with
the way the C grammar treats typedef names. In this case, the typedef
really isn't necessary; it's probably better to use a struct tag
directly. You might then have:

struct ImageT {
char magicNum[2];
int width;
int height;
int maxGrey;
int pixels[ROW][COLUMN];
};

and you would then refer to the type as "struct ImageT" rather than as
just "ImageT". That would likely have prevented the problem you're
seeing, since it's far more obvious that "struct ImageT" is a type
name, not a variable name. There are other good reasons for this
approach.

On the other hand, the typedef approach you're using is legitimate,
and some people prefer it.
 
F

Flash Gordon

danu said:
I have a structure :

typedef struct{
char magicNum[2];
int width;
int height;
int maxGrey;
int pixels[ROW][COLUMN];
} ImageT;

This defines ImageT as being an alias for a type, not a variable.
When I try to code this statement:

fscanf(infile, "%c", ImageT.magicNum[0]);

Trying to access an element in a type, instead of an element in a
variable of that type?
there is an error messege saying:

error: syntax error before 'ImageT'

What's the reason for that? What am I doing wrong here?

What you are doing wrong is not reading your C text book to find out
what typedef does.
 
B

Ben Pfaff

danu said:
typedef struct
char magicNum[2]
int width
int height
int maxGrey
int pixels[ROW][COLUMN]
} ImageT

When I try to code this statement

fscanf(infile, "%c", ImageT.magicNum[0])

there is an error messege saying

error: syntax error before 'ImageT
You defined a structure type and gave it a typedef name ImageT
You didn't define any object of type ImageT
The . operator works on objects, not on types
 
M

Martin Ambuhl

danu said:
I have a structure :

typedef struct{
char magicNum[2];
int width;
int height;
int maxGrey;
int pixels[ROW][COLUMN];
} ImageT;

When I try to code this statement:

fscanf(infile, "%c", ImageT.magicNum[0]);

there is an error messege saying:

error: syntax error before 'ImageT'

ImageT is the name of a type, not of an object.
 
D

Daniel Rudy

At about the time of 12/1/2005 3:53 PM, danu stated the following:
I have a structure :

typedef struct{
char magicNum[2];
int width;
int height;
int maxGrey;
int pixels[ROW][COLUMN];
} ImageT;

When I try to code this statement:

fscanf(infile, "%c", ImageT.magicNum[0]);

there is an error messege saying:

error: syntax error before 'ImageT'

What's the reason for that? What am I doing wrong here?
thanks.

Personally, I see a couple of problems with this (someone please correct
me if I'm wrong).

typedef struct ImageT_tag__ {
char magicNum[2];
int width;
int maxGrey'
int pixels[ROW][COLUMN];
} ImageT;


ImageT ImageTvar;

fscanf(infile, "%c", &ImageT.magicNum[0]);


Now this brings up a very interesting question in C89. I've actually
had code that refused to compile unless I placed an identifier after the
struct. Is that part of the standard, or is it just a gcc thing?

--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fcsk more fcsk yes spray umount sleep
 
K

Keith Thompson

Daniel Rudy said:
Personally, I see a couple of problems with this (someone please correct
me if I'm wrong).

typedef struct ImageT_tag__ {
char magicNum[2];
int width;
int maxGrey'
int pixels[ROW][COLUMN];
} ImageT;


ImageT ImageTvar;

fscanf(infile, "%c", &ImageT.magicNum[0]);

This fixes the type error from the original code, but it has the same
problem that it uses ImageT as if it were a variable name, when in
fact it's a type name. Presumably you meant

fscanf(stdin, "%c", &ImageTvar.magicNum[0]);

It's always a good idea to compile your code before posting it; that
would have caught both this error and the syntax error in the
declaration of maxGrey.
Now this brings up a very interesting question in C89. I've actually
had code that refused to compile unless I placed an identifier after the
struct. Is that part of the standard, or is it just a gcc thing?

As far as I know, it's neither. Can you show an example?
 
D

Daniel Rudy

At about the time of 12/2/2005 1:17 AM, Keith Thompson stated the following:
Personally, I see a couple of problems with this (someone please correct
me if I'm wrong).

typedef struct ImageT_tag__ {
char magicNum[2];
int width;
int maxGrey'
int pixels[ROW][COLUMN];
} ImageT;


ImageT ImageTvar;

fscanf(infile, "%c", &ImageT.magicNum[0]);


This fixes the type error from the original code, but it has the same
problem that it uses ImageT as if it were a variable name, when in
fact it's a type name. Presumably you meant

fscanf(stdin, "%c", &ImageTvar.magicNum[0]);

It's always a good idea to compile your code before posting it; that
would have caught both this error and the syntax error in the
declaration of maxGrey.

Yeah, I was dead tired and on my way to bed when I wrote that. I make
no excuse though.
As far as I know, it's neither. Can you show an example?

I stand corrected, it was a warning, but the type name didn't register
properly which caused errors later on. Look at the struct above, but
omit the ImageT_tag__ identifier. I was using gcc at the time.
Something about useless statement.

--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fcsk more fcsk yes spray umount sleep
 
C

Chris Torek

Daniel Rudy said:
typedef struct ImageT_tag__ {
char magicNum[2];
int width;
int maxGrey'
int pixels[ROW][COLUMN];
} ImageT;
ImageT ImageTvar;

fscanf(infile, "%c", &ImageT.magicNum[0]);
At about the time of 12/2/2005 1:17 AM, Keith Thompson stated the following:
This fixes the type error from the original code, but it has the same
problem that it uses ImageT as if it were a variable name, when in
fact it's a type name. Presumably you meant

fscanf(stdin, "%c", &ImageTvar.magicNum[0]);

It's always a good idea to compile your code before posting it; that
would have caught both this error and the syntax error in the
declaration of maxGrey.

Yeah, I was dead tired and on my way to bed when I wrote that. I make
no excuse though.

"foo.c, line 27: warning: code written and posted by tired programmer" :)

(Or, as another joke in math / physics goes, "don't drink and
derive", although in that case, the brain fatigue is from something
other than inappropriate neurotransmitter levels.)
I stand corrected, it was a warning, but the type name didn't register
properly which caused errors later on. Look at the struct above, but
omit the ImageT_tag__ identifier. I was using gcc at the time.
Something about useless statement.

I think you are mixing up a couple of concepts again here. GCC
(and some other compilers) will gripe -- usually with a "warning"
rather than an "error" -- if you do something like
this:

static int;

and:

typedef double;

both of which are useless since they do not declare any names to
be "int"s (in the first case) or "double" aliases (in the second).

Now, as it happens, there are a lot of people who -- for whatever
reason -- internalise the "struct" definition syntax incorrectly.
The actual syntax is:

struct some_tag_name {
... contents ...
} /* optionally, variable names here too */;

where the keyword "struct" and the braces are required, the "structure
tag" name is sometimes optional, and the "contents" need to include
at least one type-and-member-name.

The tag is in fact *required* whenever any structure
is to contain a pointer to this structure (which has not yet
been completely defined, because we have not yet reached the
close "}" that ends the definition of the members). One very
common case in which this structure is to contain a pointer
to another instance of itself, as in a linked-list:

struct foo_list {
struct foo_list *next;
...
};

Here, regardless of the use (or lack thereof) of typedef-aliases,
the tag is required.

Because a tag is sometimes required, I encourage neophyte C
programmers to use one every time, not just when it is required.
This eliminates the need to think about whether the tag name is
required. Of course, it replaces this need with the need to think
of a good name, which may be even harder; but thinking of good
names is good practice, too. :)

Where people seem to become confused is when they start using
"typedef".

The syntax for C's typedef is quite odd. In other languages,
variable and type declarations tend to have wildly different
syntaxes:

var i, j: integer;
type my_type_index is integer range 0 .. 999;
type my_type_struct is record
... list of "record" entries ...
end record;
var x: my_type_index;
var s: array [my_type_index] of my_type_struct;

Here a variable declaration lists the variables, then uses a
punctuator (":"), then gives the type of those variables; but
a type-definition names the type, then uses a keyword ("is"),
then states what the type is supposed to be.

C, on the other hand, declares variables by having the programmer
write down a type-name, then list the variables along with any
modifiers. To declare a type alias (because typedef does not create
a new type, just an alias for an existing one), C has the programmer
write the type and the alias as if it were a variable declaration,
then prefix the whole shebang with the keyword "typedef":

int i, j;
typedef int my_type_index; /* C does not have subranges */
typedef struct my_type_struct {
... list of entries ...
} my_type_struct;
my_type_index x;
my_type_struct s[1000]; /* can't use a subrange to define the range */

This makes typedef act, syntactically speaking, like a storage-class
specifier ("register", "static", or "auto"):

void f(void) {
register int i, *j;
static int k, *m;
typedef int n, *p, q;
...
}

Here n, *p, and q are all type-aliases for "int". Since *p is an
alias for "int", p must be an alias for "pointer to int".

The critical thing to remember here is that typedef is just pasted
on in front of a regular variable declaration. Inside the compiler,
the "typedef" keyword sets a flag:

"Whenever you are about to enter a variable name into your
tables, instead of marking it as `x is a variable that has
type T', mark it instead as `x is an alias for type T'."

Thus, if p would have been a variable of type "pointer to int", it
gets marked as "alias for pointer to int" instead.

Now, suppose we define a new structure type:

struct mylist {
struct mylist *next;
char *name;
int value;
};

We can then define some variables with that type:

struct mylist second_item; /* forward declaration */

struct mylist first_item = { &second_item, "hello", 1 };
struct mylist second_item = { NULL, "world", 2 };

But we can sneak those in with the definition of the structure
type too (and at the same time, reverse the order to get rid of
the forward declaration):

struct mylist {
struct mylist *next;
char *name;
int value;
} second_item = { NULL, "world", 2 },
first_item = { &second_item, "hello", 1 };

But if we can declare variables, we can stick a typedef keyword
on the front of the whole thing and turn the variables into
type-names. (Of course, we have to get rid of the initializers:
only variables, not type-aliases, can be initialized.) This
gives something like:

typedef struct mylist {
struct mylist *next;
char *name;
int value;
} ALIAS1, *ALIAS2, ALIAS3[100];

With this monster combination construct, we have simultaneously
declared a new type ("struct mylist") and defined it ("{ ... }"),
then declared three aliases that are connected with it. The first
(ALIAS1) is an alias for "struct mylist"; the second (ALIAS2) is
an alias for "struct mylist *"; and the third (ALIAS3) is an alias
for "struct mylist [100]" -- a type-name that looks peculiar in C,
because the name of the variable itself is missing; but this is
how one turns variable-names into type-names (just drop the
variable-name).

[Aside: this is why C's pointer-to-function types look so odd.
If fp is a variable of type "pointer to function taking double
and returning int", it is declared as:

int (*fp)(double);

which looks bad enough to start with. To turn that into a type
name instead of a variable name, we drop the variable's name (and
the semicolon):

int (*)(double)

Typically this type-name would be used in a cast, so the whole
thing would get one additional set of parentheses, and be placed
in front of some other expression. We might use that to convert
a value stored in a variable of type "pointer to function (void)
returning void" to the presumably-correct type, and call the
resulting function:

int result;
...
result = ((int (*)(double))lookup("func"))(3.14159265358979323846);

This would likely be more readable and maintainable if we used
several intermediate variables, though.]

Returning to structures and typedefs, though: for some reason, a
lot of programmers seem to wind up thinking that it is "typedef"
that defines types. (Perhaps it has to do with the fact that the
word typedef is an obvious contraction for "type define", which
logically ought to define types. But C is C: typedef instead means
"define a new alias, not a new type at all", just as "static" has
nothing to do with electricity and "auto" is not a car, which is
good since you cannot "register" it with the motor vehicle department
either. :) )

The crucial point here, really, is that typedef does not define
new types. Instead, it turns what would have been variable
declarations into type-alias declarations. Declare some variables,
stick "typedef" on the front, and you have made some type-aliases
instead. To define a truly *new* type in C, your best bet is the
"struct" keyword:

struct my_type { double value; };

makes a new type that is different from every existing type, even
one that has the same contents:

struct temperature { double value; };
struct pressure { double value; };

void f(void) {
struct temperature hot;
struct pressure high;
...
hot = high; /* ERROR -- diagnostic required */
...
}

(You can also define new types with "union" and "enum", but the
latter two are limited; "struct" is not. Being unlimited is often
a mixed blessing -- "goto" is unlimited while structured looping
constructs like "for" and "while" are limited -- but in this case,
doing a cost/benefit analysis for struct vs union-or-enum usually
results in choosing "struct", at least for me.)
 
D

Daniel Rudy

At about the time of 12/4/2005 10:38 AM, Chris Torek stated the following:
(You can also define new types with "union" and "enum", but the
latter two are limited; "struct" is not. Being unlimited is often
a mixed blessing -- "goto" is unlimited while structured looping
constructs like "for" and "while" are limited -- but in this case,
doing a cost/benefit analysis for struct vs union-or-enum usually
results in choosing "struct", at least for me.)

Actually, unions have their place. The ability to take a int and break
it into bytes in quite useful at times.

union __break_int_tag
{
unsigned int integer;
unsigned char bytes[sizeof(integer)];
}

But then portability issues arise when you do this because of the
endiness of the machine.

--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fcsk more fcsk yes spray umount sleep
 
J

Jordan Abel

At about the time of 12/4/2005 10:38 AM, Chris Torek stated the following:
(You can also define new types with "union" and "enum", but the
latter two are limited; "struct" is not. Being unlimited is often
a mixed blessing -- "goto" is unlimited while structured looping
constructs like "for" and "while" are limited -- but in this case,
doing a cost/benefit analysis for struct vs union-or-enum usually
results in choosing "struct", at least for me.)

Actually, unions have their place. The ability to take a int and break
it into bytes in quite useful at times.

union __break_int_tag
{
unsigned int integer;
unsigned char bytes[sizeof(integer)];
}

But then portability issues arise when you do this because of the
endiness of the machine.

Actually, they may or may not arise sometime after you do this. It
affects strict conformance only when your output depends on the values
of the bytes after storing the int [or vice versa] It only invokes
undefined behavior if and when you attempt to store an unobserved bit
pattern into the bytes and then read the int.
 
K

Kenny McCormack

At about the time of 12/4/2005 10:38 AM, Chris Torek stated the following:
(You can also define new types with "union" and "enum", but the
latter two are limited; "struct" is not. Being unlimited is often
a mixed blessing -- "goto" is unlimited while structured looping
constructs like "for" and "while" are limited -- but in this case,
doing a cost/benefit analysis for struct vs union-or-enum usually
results in choosing "struct", at least for me.)

Actually, unions have their place. The ability to take a int and break
it into bytes in quite useful at times.

union __break_int_tag
{
unsigned int integer;
unsigned char bytes[sizeof(integer)];
}

But then portability issues arise when you do this because of the
endiness of the machine.

This newsgroup is a minefield. Guess what you just stepped on (or in) ?
 

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

Forum statistics

Threads
473,731
Messages
2,569,432
Members
44,832
Latest member
GlennSmall

Latest Threads

Top