Variable declaration - Is this valid in standard C?

K

Kannan

Its been a while I have done pure C programming (I was coding in C++).

Is the following function valid according to standard C?

int main(int argc, char *argv[])
{
int x;
x = 9;
printf("Value of x is: %d\n", x);

int i; /* <==== Is this declaration valid?*/

for(i=0; i < 10; i++)
printf("Value of i is: %d\n", i);

}

Its compiling in gcc (ver 3.4.0) and cc (ver 6). For gcc I tried the to
compile with "-x c" and "-ansi" option (gcc -x c -ansi <sourcefile.c>)
the result is same. What I remember from when I was doing C programs
actively was this will give you a compile error.

Please tell me what is the standard about this?


I have one more question

If I declare the variable "i" in "for" loop like this
.......................
for(int i=0; i < 10; i++)
...............................

Then
1. When I compile with gcc (Command line $gcc <sourcefile.c>) gives me
an error "10: error: 'for' loop initial declaration used outside C99
mode".

2. When I compile with cc (command line $cc <sourcefile.c>) its
compiling and producing the binary executable.

I am bit confused here !?!?
Any comments appreciated.

Thank you for your time.
-Kannan
 
W

Walter Roberson

Kannan said:
Is the following function valid according to standard C?
int main(int argc, char *argv[])
{
int x;
x = 9;
printf("Value of x is: %d\n", x);
int i; /* <==== Is this declaration valid?*/

Not in C89, but Yes in C99.
for(i=0; i < 10; i++)
printf("Value of i is: %d\n", i);
}

Its compiling in gcc (ver 3.4.0) and cc (ver 6). For gcc I tried the to
compile with "-x c" and "-ansi" option (gcc -x c -ansi <sourcefile.c>)
the result is same. What I remember from when I was doing C programs
actively was this will give you a compile error.

specific gcc options are off-topic, but try -std=c89

I have one more question
If I declare the variable "i" in "for" loop like this
......................
for(int i=0; i < 10; i++)
..............................
Then
1. When I compile with gcc (Command line $gcc <sourcefile.c>) gives me
an error "10: error: 'for' loop initial declaration used outside C99
mode".

A correct diagnostic.

2. When I compile with cc (command line $cc <sourcefile.c>) its
compiling and producing the binary executable.
I am bit confused here !?!?

cc on your [unnamed] platform might default to c99, or might
default to supporting those kinds of declarations as a nonstandard
extension.
 
R

Richard Heathfield

Kannan said:
Its been a while I have done pure C programming (I was coding in C++).

Is the following function valid according to standard C?

int main(int argc, char *argv[])
{
int x;
x = 9;
printf("Value of x is: %d\n", x);

int i; /* <==== Is this declaration valid?*/

Yes and no!

In C as standardised in 1989 by ANSI and adopted by ISO in 1990, the answer
is "no". But the language was revised in 1999, and this was made legal. On
the other hand, not all compilers - in fact, hardly any - fully conform to
the new standard, and so the most portable thing to do is to avoid such a
usage, at least for the time being.
I have one more question

If I declare the variable "i" in "for" loop like this
......................
for(int i=0; i < 10; i++)

Same applies - see above.
 
J

jacob navia

Richard said:
In C as standardised in 1989 by ANSI and adopted by ISO in 1990, the answer
is "no". But the language was revised in 1999, and this was made legal. On
the other hand, not all compilers - in fact, hardly any - fully conform to
the new standard, and so the most portable thing to do is to avoid such a
usage, at least for the time being.

To the original poster:

Please diregard this nonsense. Many compilers support c99,
gcc supports it with the command line option
-std=c99

Note that standard C accepts this. Notable exception is
microsoft, that refuses the current standard. But you haven't
this problem since gcc supports it.

jacob
 
W

Walter Roberson

Richard Heathfield wrote:

To the original poster:
Please diregard this nonsense. Many compilers support c99,
gcc supports it with the command line option
-std=c99

Richard said "fully conform". gcc's c99 does not fully conform.

Note that standard C accepts this. Notable exception is
microsoft, that refuses the current standard. But you haven't
this problem since gcc supports it.

In that last sentance, "it" can only refer to "the current standard"
and that in turn must refer back to "standard C". The C99 standard does
accept the construct, but it is not the case that gcc fully supports the
C99 standard. Richard is warning that it is not presently a good idea to
rely on C99 extensions, because most compilers [including gcc] that
-claim- C99 support are broken in various respects.
 
A

Ancient_Hacker

int main(int argc, char *argv[])
{
int x;
x = 9;
printf("Value of x is: %d\n", x);

int i; /* <==== Is this declaration valid?*/


I *think* it's okay in C *if* it's at the beginning of a block. So if
you write:

int main(int argc, char *argv[])
{
int x;
x = 9;
printf("Value of x is: %d\n", x);

{ int i; blah blah blah statements using "i" }

then that would be okay. Note that the {}'s don't have to be "useful",
as in delimiting a compound statement. They're threre just to delimit
the scope of the declarations.
 
S

Stephen Sprunk

Kannan said:
Its been a while I have done pure C programming (I was coding in
C++).

Is the following function valid according to standard C?

int main(int argc, char *argv[])
{
int x;
x = 9;
printf("Value of x is: %d\n", x);

int i; /* <==== Is this declaration valid?*/

for(i=0; i < 10; i++)
printf("Value of i is: %d\n", i);

}

Its compiling in gcc (ver 3.4.0) and cc (ver 6). For gcc I tried the
to
compile with "-x c" and "-ansi" option (gcc -x c -ansi
<sourcefile.c>)
the result is same. What I remember from when I was doing C programs
actively was this will give you a compile error.

Please tell me what is the standard about this?

It's legal in C99, but not in C89.

<OT>However, by default GCC accepts it even when run with "-ansi" or
"-std=c89"; you need "-pedantic" to turn off many GNU extensions such
as this one. said:
I have one more question

If I declare the variable "i" in "for" loop like this
......................
for(int i=0; i < 10; i++)
..............................

Then
1. When I compile with gcc (Command line $gcc <sourcefile.c>) gives
me an error "10: error: 'for' loop initial declaration used outside
C99
mode".

That is correct; that is not legal C89.

<OT>GCC needs -std=c99 to accept this code. As to why GCC accepts the
former by default but not the latter, you'll have to ask over in
gnu.gcc.help. said:
2. When I compile with cc (command line $cc <sourcefile.c>) its
compiling and producing the binary executable.

I am bit confused here !?!?

It appears your "cc" either defaults to C99 mode or has an extension
which allows that which is on by default. Figure out how to run it in
C89 mode and it should complain too.

In general, if you're sure your code will only be used on platforms
that have a reasonably-conforming C99 compiler, feel free to use the
new features (such as this one). However, if you're going to be
distributing your code widely, it's best to stick to C89.

S
 
K

Keith Thompson

jacob navia said:
To the original poster:

Please diregard this nonsense. Many compilers support c99,
gcc supports it with the command line option
-std=c99

To the original poster:

Richard is entirely correct; jacob is wrong.

Many compilers support *some* C99 features. gcc with its "-std=c99"
option supports some, but not all, of C99; see
<http://gcc.gnu.org/c99status.html> for details. (The server seems to
be down at the moment.)

The ability to declare a variable in a for loop happens to be one of
the C99 features that gcc does support, and it's fairly likely that
any compiler that supports *some* C99 features will support that one,
along with "//" comments and mixed declarations and statements.

But if you want your code to be maximally portable, it needs to be
portable to compilers that support only C90. In this case, it's very
easy to do; just move the variable declaration outside the for loop
(and before any other statements).

Being able to localize the control variable of a for loop is a nice
feature, but it's not universally supported.

If the convenience of being able to use a few C99-specific features is
more important to you than the ability to compile your code with
compilers that don't support those features, that's fine; use them in
good health. You should just be aware of the tradeoffs.

(I honestly don't know why jacob has such trouble understanding this,
or at least cknowledging it.)
 
K

Keith Thompson

Ancient_Hacker said:
int main(int argc, char *argv[])
{
int x;
x = 9;
printf("Value of x is: %d\n", x);

int i; /* <==== Is this declaration valid?*/


I *think* it's okay in C *if* it's at the beginning of a block.

In C90, a block (the thing delimited by the '{' and '}' characters)
contains zero or more declarations followed by zero or more
statements; a declaration following a statement is illegal. In C99,
you can freely mix declarations and statements within a block. C99 is
not yet universally supported.

<OT>C++ also allows declarations and statements to be mixed. Some C
programmers make the mistake of compiling their code with a C++
compiler, which can mask some errors.</OT>

(Ancient_Hacker: There's no need to guess; plenty of people here
actually know this stuff.)
 
J

jacob navia

Please:
The question was

Is this valid in standard C?

And I answer

YES it is valid in standard C!!!!

And if your compiler is BROKEN and doesn't support standard C
use another one!

The original poster did not mention portability to old broken
stuff, and it did not mention C370, or C90 or C80 or C70!!!

And yes, C89 is not portable to old PDP 11 simulators.

This group is always trying to destroy C and to deny
all progress done since more than 10 years of standard
C development.

The differences between gnu c99 implementation and
the standard are absolutely MINOR and only known
to specialists in that matter. To use that to say
the gcc compiler supports some features of c99 only
is a gross misrepresentation of facts.

If we use the same criteria gcc doesn't compile
C++. It still has a lot to go to implement 100%
of that standard.
 
R

Richard Heathfield

Keith Thompson said:

If the convenience of being able to use a few C99-specific features is
more important to you than the ability to compile your code with
compilers that don't support those features, that's fine; use them in
good health. You should just be aware of the tradeoffs.

(I honestly don't know why jacob has such trouble understanding this,
or at least cknowledging it.)

I covered that a day or two ago.
 
R

Richard Heathfield

jacob navia said:
Please:
The question was

Is this valid in standard C?

And I answer

YES it is valid in standard C!!!!

Indeed it is valid in standard C, but not everybody has a C compiler that
fully conforms to the current standard, so it makes sense to point out the
fact that the feature in question is not fully portable, and so should be
avoided if portability is an issue.
And if your compiler is BROKEN and doesn't support standard C
use another one!

If it's broken, by all means use another one, but it isn't necessarily
broken just because it isn't fully conforming to C99. After all, gcc isn't,
Visual C isn't, and that's enough to be going on with. Are you seriously
suggesting that these two compilers are "BROKEN"?
The original poster did not mention portability to old broken
stuff, and it did not mention C370, or C90 or C80 or C70!!!

The original poster was concerned about whether the code was standard C; he
would not have asked if he did not have some reason to need to observe the
Standard - whether it be for contractual reasons, or for portability
reasons, or whatever - but he didn't mention the reason. It is likely,
although not guaranteed, that his concern was in fact portability.
And yes, C89 is not portable to old PDP 11 simulators.

I'd be surprised if that were true, but it's irrelevant.
This group is always trying to destroy C and to deny
all progress done since more than 10 years of standard
C development.

Nonsense. As soon as C99 becomes fully as portable as C89, the issue of
portability will fall by the wayside, and we can stop mentioning it. And
nothing would delight us more! But that time is not yet here.
The differences between gnu c99 implementation and
the standard are absolutely MINOR and only known
to specialists in that matter. To use that to say
the gcc compiler supports some features of c99 only
is a gross misrepresentation of facts.

No, it's a correct representation of the situation.
If we use the same criteria gcc doesn't compile
C++. It still has a lot to go to implement 100%
of that standard.

Indeed, and that's why you will probably avoid C++ if portability is very
important to you.
 
K

Keith Thompson

jacob navia said:
Please:
The question was

Is this valid in standard C?

And I answer

YES it is valid in standard C!!!!

Correct; officially, the current C standard is the one issued by ISO
in 1999. That standard is not yet as widely implemented as the
earlier standard issued by ISO in 1990, as you should know very well.
And if your compiler is BROKEN and doesn't support standard C
use another one!

That is not always possible, as you should know very well.
The original poster did not mention portability to old broken
stuff, and it did not mention C370, or C90 or C80 or C70!!!

And yes, C89 is not portable to old PDP 11 simulators.

The OP didn't mention PDP 11 simulators, or C370. I don't know what
you mean by C80 or C70.

The C90 standard is supported by almost all current C compilers. I
don't know of a significant platform which has a C compiler but
doesn't have a conforming C90 compiler (ignoring minor bugs, which
exist in virtually all software).

Some systems with pre-ANSI compilers are probably still in use.
Anyone who needs advice about programming in C on such a system can
always ask here. I don't often see such questions these days, but
I'll be glad to do my best to answer them. (My first piece of advice
would be to obtain a conforming C89/C90 compiler if possible; if
that's not possible, there are alternatives I can suggest.)

If you write code that restricts itself to the C90 standard, while
avoiding any incompatible changes in C99 (for example, that avoids
using "inline" and "restrict" as identifiers), that code will be
significantly more portable than code that depends on features that
are in C99 but not in C90.

Of course, such code is valid C99 as well.
This group is always trying to destroy C and to deny
all progress done since more than 10 years of standard
C development.

That is complete and utter nonsense, as you should know very well.

On a personal note, jacob, this kind of deliberate misrepresentation
of other people's statements is probably the most offensive and
annoying thing you do here. Knock it off.

I would be delighted if C99 enjoyed the same level of support as C90.
There are some (but not all) features of C99 that I'd like to be able
to use, and would use without hesitation if they were sufficiently
widely available. But the fact is that I cannot do that.
The differences between gnu c99 implementation and
the standard are absolutely MINOR and only known
to specialists in that matter. To use that to say
the gcc compiler supports some features of c99 only
is a gross misrepresentation of facts.

That's what the gcc project's own web site says, as you should know
very well.

There are features of C99 that gcc does not support. You deliberately
omitted that fact in your response. Why are you trying to hide the
truth, when the gcc project itself explicilty acknowledges it?
If we use the same criteria gcc doesn't compile
C++. It still has a lot to go to implement 100%
of that standard.

I have no idea whether that's true or not; in any case, it's
completely off-topic here, as you should know very well.

I provided information that could be useful to the OP, information
that you deliberately withheld. You deliberately implied that gcc is
a conforming C99 compiler; it clearly is not. It may be close enough
for some particular user's purposes, and if so, that's find. But such
a user needs to have the opportunity to understand what it supports
and what it doesn't, and make that decision for himself.

And even if the latest version of gcc completely and flawlessly
supported the C99 standard, there are plenty of systems that use older
versions of gcc, and a typical user very likely doesn't have the
ability to upgrade the compiler. Furthermore, gcc does not include
the runtime library; rather, programs generated by gcc use whatever
runtime library is provided on the system. In many cases, that
runtime library does not support certain required features of C99.

For example, consider this program:

#include <stdio.h>
#include <math.h>
int main(void)
{
double x = sqrt(2.0);
printf("x = %a\n", x);
return 0;
}

On one system with gcc 3.4.5, it correctly prints:

x = 0x1.6a09e667f3bcdp+0

On another, with gcc 4.0.2, it prints

x = a

because the runtime library (which I'm not able to replace) doesn't
support printf's "%a" format.

But you insist, without qualification, that gcc supports C99, when in
fact it only partially supports it, as you should know very well.

I don't expect to convince you of anything. I've tried and failed
before; I don't expect to succeed this time. I post this as a warning
to others that jacob navia, for whatever reason, apparently wishes to
conceal these facts from programmers who may need to know them.
 
K

Kannan

Thank you folks for your help and comments. I decided to stick to C89
standards for the current project.

About the cc compiler; I found the compiler options to compile in 6 or
7 different language levels (don't know the fine difference between
some of them).

Thank you once again.
-Kannan
 
C

Clever Monkey

jacob said:
Please:
The question was

Is this valid in standard C?

And I answer

YES it is valid in standard C!!!!
Say it brother! AMEN!
And if your compiler is BROKEN and doesn't support standard C
use another one!
YOW! All these CAPS and EXCLAMATION points are making me DIZZY!
The original poster did not mention portability to old broken
stuff, and it did not mention C370, or C90 or C80 or C70!!!

And yes, C89 is not portable to old PDP 11 simulators.
That word "portable". You keep using it. I do not think it means what
you think it means. Try using "inconceivable", instead.
This group is always trying to destroy C and to deny
all progress done since more than 10 years of standard
C development.
Thus, I believe if you look at the c.l.c charter, you will see that the
first statement indicates comp.lang.c is charged with "denying all
progress of the language with the eventual aim of destroying it".

The first step is to ensure that as many people will a poor
understanding of "portability", "standardization" and "development
practices" post as often as possible in order to share these
misunderstandings.
The differences between gnu c99 implementation and
the standard are absolutely MINOR and only known
to specialists in that matter. To use that to say
the gcc compiler supports some features of c99 only
is a gross misrepresentation of facts.
For now, every smart coder knows that C89 conventions are best, unless
you enjoy looking forward to tears and recriminations. Hence, Richard's
caveats regarding why some conventions are not common. C is a living
language, and the standards are important, but it is not the only thing.

Case in point: many new coders come to my company expecting their C code
to compile when they declare variables anywhere they want. Guess which
new coders end up knocking on my door to ask why their new code won't
compile? Looks like the compiler toolchain they use at school is
different than the one we use. Since we have no reason to move to C99,
and few compilers reliably conform to C99, we have not moved to C99.

Standards are not equivalent to best practices and coding conventions.
Each can inform the other, but they inhabit different conceptual spaces.
If we use the same criteria gcc doesn't compile
C++. It still has a lot to go to implement 100%
of that standard.
Straw-man argument. Why mention a completely different standard for a
completely different language? The gcc toolchain includes a variety of
other compilers (hint: "gcc" is _not_ an acronym for "Gnu C Compiler").
Why stop there? How conforming is the Fortran compiler? The
COBOL-to-C translator? How does any of it impact the C89, C99
standards, or the specific Gnu implementation of those standards?
 
A

Ancient_Hacker

Keith said:
(Ancient_Hacker: There's no need to guess; plenty of people here
actually know this stuff.)


Yes, but looking at this and other threads, it seems the more they
know, the less they're likely to help the original poster, but instead
veer off into a C89/99/C++ standards catfight.

The addition of two little {}'s not only conforms to the all the
standards, but is a lot easier than having the poor sod rearrange code
or dredge up a different compiler.
 
C

Clever Monkey

Ancient_Hacker said:
Yes, but looking at this and other threads, it seems the more they
know, the less they're likely to help the original poster, but instead
veer off into a C89/99/C++ standards catfight.
The usual bitching aside, Richard's original comments are still the
clearest: such declarations are C99 conforming, but it is still
advisable to use the more portable declarations, which would be
conforming to C99 (and nearly everything else) anyway.

This is the typical "yes, with caveats" answer that the entire technical
world runs on. I am as surprised as you that this simple, correct
answer generated so much traffic!
The addition of two little {}'s not only conforms to the all the
standards, but is a lot easier than having the poor sod rearrange code
or dredge up a different compiler.
Tweaking scope by using {} blocks is often just an egregious hack. I'm
not sure I agree this is any easier than simply living with C99 code
that may not be optimally portable now, or moving the declarations to
the top of a useful and expected code block.

Perhaps it is unfair, but if I was reviewing code that used braces in
this manner without a good reason (and, "I don't want to have to declare
an iterator at the top of the function" is not a good reason in this
shop) I would reject the changes. Such code is, quite simply, going to
be harder to maintain over the years. Logic changes. Loops and
branches evolve. Twiddling with scope in this manner, for little
benefit, is just asking to introduce hard-to-find bugs.

No one seriously suggests dredging up a different compiler, as long as
the compiler is reasonably conforming to one of the major standards.
Moving declarations to the top of an existing block should not be a
hardship.
 
R

Richard Heathfield

Clever Monkey said:

Tweaking scope by using {} blocks is often just an egregious hack.

Absolutely right. And I use it often. I hasten to add, however, that I don't
do this in production code. For example, if you were to look over my
shoulder at about 3am, you might see something like this:

...
foo(maybe, this);
bar(maybe, that);
baz(maybe, the, other);

{
int i;
for(i = 12; i < 17; i++)
{
printf("sheesh - maybe[%d] points to %p\n", (int)i, (void *)maybe);
}
}

By 3:20am, it would almost certainly be gone.
 
A

Al Balmer

Yes, but looking at this and other threads, it seems the more they
know, the less they're likely to help the original poster, but instead
veer off into a C89/99/C++ standards catfight.
Not so, as the current thread shows. The original post was answered
immediately and correctly by two persons who know a great deal. It was
only then that another poster who knows somewhat less started the
catfight.
The addition of two little {}'s not only conforms to the all the
standards, but is a lot easier than having the poor sod rearrange code
or dredge up a different compiler.

IMO, it's not easier than the trivial rearranging of code required,
and is unnecessary obfuscation. If I saw that code, I would look
again, wondering why on earth the programmer did it. Granted, it
wouldn't take long to see that there was no particularly good reason,
but why do it?
 
J

jaysome

Clever Monkey said:

Tweaking scope by using {} blocks is often just an egregious hack.

Absolutely right. And I use it often. I hasten to add, however, that I don't
do this in production code. For example, if you were to look over my
shoulder at about 3am, you might see something like this:

...
foo(maybe, this);
bar(maybe, that);
baz(maybe, the, other);

{
int i;
for(i = 12; i < 17; i++)
{
printf("sheesh - maybe[%d] points to %p\n", (int)i, (void *)maybe);
}
}

By 3:20am, it would almost certainly be gone.


That's forgivable, just like this is:

/* standard includes follow */
....
int main(void)
{
....
{
char s[65536];/* Use a size that guarantees, beyond a reasonable
doubt, that no undefined behavior will taint the results. I well could
have used char s[2], because I know how to walk the bad dog. However,
at 3:00am my mind can play some wicked tricks on me--better to be safe
and use a Standard C function like gets() and give it enough fuel :)
*/

/* I never use getc() or getch() or getchar() or whatever it's called,
and therefore I can't remember what it's called--so instead of trying
to remember/use one of these and risk a compilation error, I'll just
cut to the chase and use gets(), which I know will work for this
purpose. */
gets(s); /* force Command Prompt window to stay around so I can look
at program output */
}
....
return !-1;/*success!!!*/
}
 

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,763
Messages
2,569,562
Members
45,038
Latest member
OrderProperKetocapsules

Latest Threads

Top