Declaration of Variables: Location

N

noridotjabi

Whilest I was browesing a tutorial today I came across the infromation
that in standard C variables must be decalred at the beginning of a
block. Meaning:

/****************************************************/
/* ... usual includes and such */
int var = 1;

if(var = 1){
printf("hello world\n");
}

int a = 10;
int b = 30;

printf("%d %d", a, b);
/* end return etc. */
/****************************************************/

Would form some kind of error and would need to be replaced with:
/****************************************************/
/* ... usual includes and such */
int var = 1;
if(var = 1){
printf("hello world\n");
}

{
int a = 10;
int b = 30;
printf("%d %d", a, b);
}
/* end return etc. */
/****************************************************/

This is news to me as I have never heard or seen anything like this.
Infact I have assumed (but have never confirmed) that C was even
equiped with a "naked block" feature. Can anyone offer any insight as
to what is going on here. Also please correct me if I have
misinturpreted someting as I expect that I might have.
Nori
 
I

Ian Collins

Whilest I was browesing a tutorial today I came across the infromation
that in standard C variables must be decalred at the beginning of a
block.

True for pre C99 code, fixed in C99.
 
M

milhous.30

This is the old sytle c....now c can handle the declaration of a
variable any where, as long as it is only referenced after that point.
The standard is more strict than what most compilers accept(gcc
included). If you want strict use

gcc -pedantic ...
 
A

Andrew Poelstra

Ian said:
True for pre C99 code, fixed in C99.

I'd like to point out that code is far easier to read if all the
variable declarations are at the top of each block. It also allows you
to easily see what is and isn't in scope, assuming you indent each layer
to blocks.


Of course, that is just a preference of mine.
--
Andrew Poelstra <http://www.wpsoftware.net/blog>

Every prime number in a series as a joke
Made all the patterns clear when I took that final toke
-- Numbers (Sunken Complexity)
 
K

Keith Thompson

Andrew Poelstra said:
I'd like to point out that code is far easier to read if all the
variable declarations are at the top of each block. It also allows you
to easily see what is and isn't in scope, assuming you indent each
layer to blocks.


Of course, that is just a preference of mine.

On the other hand, it can be useful to mix declarations and statements
when an initialization depends on some previous computation in the
same block:

{
char *p = malloc(ENOUGH_BYTES);
if (p == NULL) {
exit(EXIT_FAILURE);
}
strcpy(p, some_string);
strcat(p, some_other_string);
size_t len = strlen(p);
...
}

You can usually achieve the same effect by using assignments rather
than initializations, but it's handy to be able to initialize each
variable as it's declared.
 
M

Martin Ambuhl

Whilest I was browesing a tutorial today I came across the infromation
that in standard C variables must be decalred at the beginning of a
block.

This was true before C99, but has not been for sometime.
On the other hand, it is good programming practice to declare variable
at the beginning of the block. Should you feel a real need to declare
variables elsewhere, new blocks can be created and external routine can
be used.

[example of use of a inner block snipped]
This is news to me as I have never heard or seen anything like this.
Infact I have assumed (but have never confirmed) that C was even
equiped with a "naked block" feature.

"Naked block" is not a C term. I admit my inability to make sense of
the above. Had the second sentence said something to the effect that
you assumed that C did *not* have such a feature, I would have noted
that the braces, curly brackets, or whatever you prefer to call "{" and
"}" enclose a compound statement. Compound statements are just
statement. They need no special mechanism like control-structures or
function declarations immediately preceding them.
 
B

Ben Pfaff

s/fixed/broken/.

You're the second person who's indicated a strong bias in favor
of declaring all variables at the beginning of the block. Can
you explain further? I like the idea of being able to initialize
my variables at the point of declaration whenever possible, so I
like the idea of mid-block declarations. (However, I don't
really get to use them because I also like my code to be
C89-friendly.)
 
V

Vladimir Oka

Ben said:
You're the second person who's indicated a strong bias in favor
of declaring all variables at the beginning of the block.

I'd be the third then...
Can you explain further?

I can see the benefit (or "benefit") from declaring a variable close to
the place of first use when writing code. However, when reading code, I
find it much easier to have a single, well deifned place to look up all
the variables declared in a block. You can even have that bit open in a
separate window for quick reference.
I like the idea of being able to initialize my variables at the point of
declaration whenever possible, so I like the idea of mid-block declarations.

You can still initialise the variables just before using them.
(However, I don't really get to use them because I also like my code to be
C89-friendly.)

Another good reason.
 
J

John Bode

Whilest I was browesing a tutorial today I came across the infromation
that in standard C variables must be decalred at the beginning of a
block.

[snip example]
This is news to me as I have never heard or seen anything like this.
Infact I have assumed (but have never confirmed) that C was even
equiped with a "naked block" feature. Can anyone offer any insight as
to what is going on here. Also please correct me if I have
misinturpreted someting as I expect that I might have.
Nori

For pre-C99 implementations, all block-scope variables must be declared
at the beginning of the block. For C99 implementations, block-scope
variables can be declared anywhere within a block (with the obvious
restriction that they must be declared before they're used).

I have no idea what you mean by a "naked" block. As of C99, there are
implicit blocks associated with iterative and conditional statements;
I'm not sure if this is what you're thinking about.

Like everything else in programming, it's all about tradeoffs. The
good thing about having all your variables declared at the head of the
block is that it (arguably) improves readability (if you're wondering
about whether x is int or long, you immediately know where to look).
The good thing about declaring your variables as needed throughout the
code is that it limits the scope of those variables to where they're
actually used, and reduces the chance that a variable accidentally gets
used in multiple contexts (not a common mistake IME, but it does
happen; it's usually a sign that the code needs restructuring).
 
C

CBFalconer

Vladimir said:
I'd be the third then...


I can see the benefit (or "benefit") from declaring a variable
close to the place of first use when writing code. However, when
reading code, I find it much easier to have a single, well deifned
place to look up all the variables declared in a block. You can
even have that bit open in a separate window for quick reference.


You can still initialise the variables just before using them.


Another good reason.

For once I can only agree. A further factor is that I was brought
up on more disciplined languages, such as Pascal.

On the initialization point, initialization of local variables
generates code. It just isn't as obvious. In Pascal there are no
initialization statements, so one gets in the habit of writing the
appropriate code in the appropriate places.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
 
J

Jack Klein

Whilest I was browesing a tutorial today I came across the infromation
that in standard C variables must be decalred at the beginning of a
block.

This was true before C99, but has not been for sometime.
On the other hand, it is good programming practice to declare variable
at the beginning of the block. Should you feel a real need to declare
variables elsewhere, new blocks can be created and external routine can
be used.

[example of use of a inner block snipped]
This is news to me as I have never heard or seen anything like this.
Infact I have assumed (but have never confirmed) that C was even
equiped with a "naked block" feature.

"Naked block" is not a C term. I admit my inability to make sense of
the above. Had the second sentence said something to the effect that
you assumed that C did *not* have such a feature, I would have noted
that the braces, curly brackets, or whatever you prefer to call "{" and
"}" enclose a compound statement. Compound statements are just
statement. They need no special mechanism like control-structures or
function declarations immediately preceding them.

I took the OP's use of the term "naked block" to be the technique I
sometimes use when maintaining or updating code, my own and others.

I took it to mean a block (obviously enclosed by { and }) that was
free standing, not following a if/while/do/switch statement.

Consider having to make a change to a value in a function written by
somebody else:

int the_func(int x, int y, int z)
{
int local;
/* other declarations */

/* ... */

local = some_calculation();

/* ... */

return local;
}

I have to allow for a new feature in the code. Under some
circumstances which might be complex to evaluate, the function has to
return a value completely related to that returned by
some_calculation(). Under other circumstances, is returns the
original result.

Now one thing I could do is put the "local =" statement inside an if()
with the other possibility in the else clause. But in a complex
original function, and if the test and new calculation are complex as
well, this causes enough editing to create a non-trivial chance of
introducing defects.

So I introduce a "naked block", to make sure that I don't trample on
anything in an outer scope:

int the_func(int x, int y, int z)
{
int local;
/* other declarations */

/* ... */

local = some_calculation();

{
int tst1 = some_test();
int tst2 = another_test();
int tst3 = yet_another_test();

if ((tst1 == 42) && (tst1 < tst2) && (tst3 > (tst2 - tst1)))
{
int inner = /* ... */
/* perhaps call several functions to get values, */
/* perform calculations and so on to get new return value */
local = inner;
}
}

/* ... */

return local;
}

By introducing the naked block, I create a new scope and only modify
one value outside that scope, namely to change the return value when
the appropriate conditions exist. The only way my addition can change
the behavior of the code, other than what I intended, is through side
effects of any functions called inside the block. I can't
accidentally change the value of any object that the_func() might use
after my block, because I modify only values defined within the block.

I could do the same by defining new objects at the top of the_func(),
but then I run the risk accidentally hiding a name at wider scope.
 
R

Richard Bos

Ben Pfaff said:
You're the second person who's indicated a strong bias in favor
of declaring all variables at the beginning of the block. Can
you explain further? I like the idea of being able to initialize
my variables at the point of declaration whenever possible, so I
like the idea of mid-block declarations.

I've seen too much (C-plus-extensions, pre-C99) code where declarations
were thrown into the code at any which point, without intervening
whitespace, and generally made less conspicuous with a nice, complex
initialiser which makes it look more like an ordinary assignment.
While I don't disagree that it _can_ be used correctly, the temptation
to make declarations impossible to find at a glance is apparently too
great for too many programmers.
If you really _need_ a mid-code declaration, you can always open another
block. That has the added advantage of making it stand out.

Richard
 
W

websnarf

Andrew said:
I'd like to point out that code is far easier to read if all the
variable declarations are at the top of each block. It also allows you
to easily see what is and isn't in scope, assuming you indent each layer
to blocks.

Yeah, and it also clearly deliniates between code and declarations. So
I would say it got "broken" in C99.

C++ added this because they wanted greater control over construction
(though they ignored the corresponding issue for destruction, for some
reason). The C language does not have such an issue, or even one
analogous to it.
Of course, that is just a preference of mine.

I'm with you.
 
W

websnarf

Ben said:
s/fixed/broken/.

You're the second person who's indicated a strong bias in favor
of declaring all variables at the beginning of the block. Can
you explain further? I like the idea of being able to initialize
my variables at the point of declaration whenever possible, [...]

Same here -- fortunately C89 already gives us what we need to
accomplish this via bare scope blocking. Of course you still need to
observe nesting rules, but complaining about that is analogous to
complaining that structured looping is not as flexible as goto.

You might like to compare the C99/C++'s "fix" for your desire as
compared to Java's fix for the exact same problem.
 
T

Tomás

C++ added this because they wanted greater control over construction
(though they ignored the corresponding issue for destruction, for some
reason).

I am a C++ programmer. The ability to put a variable/object declaration
anywhere in a function is beneficial when you want to pass certain arguments
to a class object's constructor. For example:

int main()
{
int i;

cin >> i; //This inputs an integral value from the user

SomeClass object(i);
//Here we can use "i" as an argument to the object's constructor
}


Not only that, but I like that I can declare variables at the point where I
need them, e.g.:

int main()
{
cout << "Would you like to proceed? ";

bool proceed; cin >> proceed;

if (!proceed) return -1;

//Now I can declare more variables:

cout << "What age are you? ";

unsigned char age; cin >> age;
}


We can use chain brackets in C++ (I presume you can do the same in C) to
limit a variable's scope:

int main()
{
int i;

k = 3; // illegal: no such variable

{
int k = 4;

i = 7; //perfectly legal
}


int k = 3; //perfectly legal, because of
//different scope. Also, the other
//"k" has been destroyed.
}


However, if you want TOTAL control over an object's construction and
destruction in C++, you can exploit "placement new", as follows:

int main()
{
void* const p = malloc( sizeof(SomeClass) );

//The memory for the class object has been allocated.
//Next, we want to call the constructor:

SomeClass* const p_object = new(p) SomeClass(7, true, 5.4);

//Now the object has been "constructed" and can be used
//however we please. . .


//When we're done with the object, we call its
//destructor, and then deallocate the memory:

(*p_object).~SomeClass();

// or alternative syntax:

p_object->SomeClass();


//Now we deallocate the memory:

free(p);

}


-Tomás
 
V

Vladimir Oka

Tomás opined:
I am a C++ programmer. The ability to put a variable/object
declaration anywhere in a function is beneficial when you want to
pass certain arguments to a class object's constructor. For example:

Be that as it may, you're posting to comp.lang.c, about an issue that
is actually not necessarily language related (call it style related,
if you will). So, you could have tried to massage your examples into
C. It wouldn't have made the difference to your point, which...

said:
int main()
{
cout << "Would you like to proceed? ";

bool proceed; cin >> proceed;

....perfectly exemplifies why I think this practice is a Bad Thing
(especially when combined with this sort of "coding style"). It takes
inordinate amount of time to unpick declaration from the statement,
and may actually fail to stand out enough on the first eyeball pass.
if (!proceed) return -1;

//Now I can declare more variables:

cout << "What age are you? ";

unsigned char age; cin >> age;

Also, this last one goes out of scope on the following line, and is so
completely useless.
< snip: more C++ >

--
Fatal Error: Found [MS-Windows] System -> Repartitioning Disk for
Linux...
(By (e-mail address removed), Christopher Browne)

<http://clc-wiki.net/wiki/Introduction_to_comp.lang.c>
 
C

CBFalconer

Andrew Poelstra wrote:
.... snip ...

Yeah, and it also clearly deliniates between code and declarations.
So I would say it got "broken" in C99.

Hallelujah and Praise to Allah. You finally said something I can
agree with.

--
"The power of the Executive to cast a man into prison without
formulating any charge known to the law, and particularly to
deny him the judgement of his peers, is in the highest degree
odious and is the foundation of all totalitarian government
whether Nazi or Communist." -- W. Churchill, Nov 21, 1943
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top