Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > syntax errror

Reply
Thread Tools

syntax errror

 
 
Daniel Rudy
Guest
Posts: n/a
 
      12-02-2005
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
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      12-02-2005
Daniel Rudy <(E-Mail Removed)> writes:
[snip]
>
> 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?

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
 
 
 
Daniel Rudy
Guest
Posts: n/a
 
      12-04-2005
At about the time of 12/2/2005 1:17 AM, Keith Thompson stated the following:

> Daniel Rudy <(E-Mail Removed)> writes:
> [snip]
>
>>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.

>>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?
>


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
 
Reply With Quote
 
Chris Torek
Guest
Posts: n/a
 
      12-04-2005
>> Daniel Rudy <(E-Mail Removed)> writes:
>>>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.


In article <6wCkf.35980$(E-Mail Removed) m>
Daniel Rudy <ZGNydWR5QHBhY2JlbGwubmV0> wrote:
>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'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?


>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.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
 
Reply With Quote
 
Daniel Rudy
Guest
Posts: n/a
 
      12-09-2005
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
 
Reply With Quote
 
Jordan Abel
Guest
Posts: n/a
 
      12-09-2005
On 2005-12-09, Daniel Rudy <(E-Mail Removed)> wrote:
> 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.
 
Reply With Quote
 
Kenny McCormack
Guest
Posts: n/a
 
      12-10-2005
In article <mgkmf.29079$(E-Mail Removed)> ,
Daniel Rudy <ZGNydWR5QHBhY2JlbGwubmV0> wrote:
>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) ?

 
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
keep getting pop: Internet explorer errror script: syntax error,JS/BrowserCompatibility lbbss Computer Support 1 11-22-2009 12:37 PM
Forms Authentication errror Sumaira Ahmad ASP .Net 1 10-28-2004 11:47 PM
Re: Server not found errror: when trying to open a file from a directo Curt_C [MVP] ASP .Net 4 07-19-2004 09:17 PM
Errror finding Chris Perl 3 07-01-2004 07:44 PM
Windows 2003 Server crashes with stop errror. Jack MCSE 4 12-11-2003 08:15 AM



Advertisments