1

I remember when David talked about declaring variables, he said we couldn't say like 'Hey computer, give me a variable called n' and then later say 'oh hey, give me another variable called n'. The code was something like:

int main(void)
{
    int n;
    do
    {
        int n = get_int("integer: ");
    }
    while (n < 0);
}

(I think) I understand the concept of scope, that if you need to use n in a later set of { }, then you need to declare it outside, as line 3 instead of line 6.

But is it perfectly legal and correct, if I only need to use a variable inside a loop to do something like:

for (int i = 0; i < 10; i++)
{
    int n;
    n = something;
}

I think I have heard that you shouldn't declare a variable more than once, else weird stuff might happen. So I thought that you couldn't declare a variable like that inside a loop, because it re-declares it every loop. Or was I mistaken, and the idea was meant with respect to scopes that touch upon each other?

1 Answer 1

1

You can do what is shown in both of your examples, but you shouldn't. The first is a very bad practice, while the second depends on how it is used.

In the first case, it's called creating a shadow variable. It is legal and possible, but almost always causes problems and leads to bugs.

A shadow variable is one that is created with the same name as an earlier variable with greater scope. In your first example, the n on line 6 is the shadow variable, shadowing the earlier n. It will mask or suspend the earlier variable while it exists. The shadow var exists while it is in scope, i.e., inside the closest pair of curly braces or parentheses that contain it. Once it goes out of scope or ceases to exist, the original var reappears to the code with whatever value it contained before being masked.

In the second example, your interpretation is correct. This practice can be either good or bad.

If the var is being used to carry a value forward from one pass through the loop to the next, the var MUST be declared before the start of the loop so that it will maintain scope and continue to exist between passes.

If the loop doesn't need to preserve data between passes, then it can be declared inside the loop and it will work, but it's still a bad practice. It's arguably better to create it before the loop and reset it's value inside the loop on each pass when needed.

Here's the argument. On one hand, declaring it inside the loop guarantees that it will go out of scope at the end of each pass and be destroyed, then recreated on the next pass. This assures that no data from the previous pass will make it's way to the next pass. This is fine when performance isn't an issue. (The program is running once, the loop is executed a small number of times in terms of computing - executing time is measured in minutes, seconds, or less. )

On the other hand, what if it's a production program that runs millions of times or has millons of copies running in parallel on the same computer. Think about an airline ticket program or Amazon.com! ANYTHING that takes extra time can have a massive impact on execution time! Now, it's far more important to look at efficiencies like this!

So, in one of our simple psets, redeclaring in the loop can be fine, but it might not be the best practice in a production environment. It's up to the programmer to decide. ;-)

If you have any questions, add them as comments.

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

2
  • So when you talk about efficiencies, isn't it inefficient to have a variable kept in memory after the loop is finished? When declaring it outside the loop, it stays 'active' in that outer scope. And should I then remember if I had used that variable earlier for a specific loop when declaring new variables in a later loop? Cause I might reuse the same name in the same scope.
    – nBock
    Commented Nov 29, 2018 at 17:42
  • So in pset4 copy.c, one of the loops look like “for (int j = 0; j < bi.biWidth; j++) { RGBTRIPLE triple; stuff }”, this would be considered ‘inefficient’ if we want to maximize performance and were scaling up? If I run copy.c with debug50, then as I pass the loop once and get to re-assign the variable, I can see it still has the previous run’s value assigned to it, before it is overwritten. Should this be the case, as it should be a ‘new’ scope given a new iteration in the loop?
    – nBock
    Commented Nov 29, 2018 at 17:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .