i was always taught put the variables u plan on using in a function at the top of it!

im curious if it's considered bad programming practice to only define variables when they are going to be used/need to be used....for example possibly midway or further into a function?

Recommended Answers

All 8 Replies

In C++ you generally create the variables where they are used...In C its considered improper programming style to mixed declarations and code but C++ its O.K.

In C++ you generally create the variables where they are used...In C its considered improper programming style to mixed declarations and code but C++ its O.K.

It's also very useful from the point of view of controlling the scope of variables in a program. For example, in the C style, you might feel like you should do:

int main(){
    /* Declare all the variables now */
    int i, j;
    std::string tempStr;
    std::vector< std::string > v;

    for(i = 0; i < 3; ++i){
        std::cout << "Enter a string: ";
        std::cin >> tempStr;
        v.push_back(tempStr);
    }

    for(j = 0; j < 3; ++j){
        tempStr = v[i];     // This is valid, will compile fine, but is *not* what we intended.
                            // It will give a difficult to find runtime bug!
        std::cout << tempStr << std::endl;
    }
}

But I would much rather use:

int main(){
    /* Only declare the variable that is needed from this point onwards */
    std::vector< std::string > v;

    for(unsigned i = 0; i < 3; ++i){   // Loop variable only in scope for the loop
        std::string tempStr;           // This is only in scope for this loop
        std::cout << "Enter a string: ";
        std::cin >> tempStr;
        v.push_back(tempStr);
    }

// i & tempStr no longer exist here

    for(unsigned j = 0; j < 3; ++j){   // Again, loop variable only valid in loop
        std::string tempStr = v[i];    // Declare and initialise temp variable
                                       // Now the compiler will complain and we can change the "i" to a "j" and compile correctly!
        std::cout << tempStr << std::endl;
    }

// Only v still exists at this point
}

This way, the loop variables i and j and the temporary variable tempStr go out of scope when you're done with them and can pose you no further problem later in the program when you accidentally forget to reset them and use them for something you shouldn't. This is a bit of a contrived example, but I hope it makes my point :)

I would go one step further than gerard4143, I would say that it is not only O.K., but considered better practice in C++ to declare variables only where they are needed. In theory, it is faster. In practice it is just nicer because it keeps things localized in the code. If you have, for example, a large algorithm in one function and it requires many temporary or helper variables to do the various mathematical manipulations it needs. If you put all the variable declarations at the beginning, when someone reads you code, every time he encounters a new variable name he will have to visually scan through possibly the entire algorithm to see if that variable is meaningful in the algorithm or just a temporary. If it is declared on-site and within a reduced scope (like an "if" statement or inner-loop) then it is clear that it is a temporary or helper variable that is not relevant to the overall algorithm but just used to perform a local operation. Also, reduction of the scope of the variables can lead to better performance and will reduce the stack usage in a large function (i.e. if you have all variables at the start, the compiler has to generate an unecessarily large stack frame for that function, and every memory access operation will potentially be more costly if the stack is too large. While local declarations will make the stack frame be incrementally increased as the scopes of the function are encountered, and overall, it will lead to a smaller stack frame, more local memory, and better performance.). You know, it is considered better practice to give sensible names to your variables such that it is clear to the reader what those variables are for. Well, you could say that keeping variable declarations local is in the same ball-park (and it also helps when you have variables that are really temporary and insignificant, instead of coming up with a name like "temporary_to_do_swap_in_second_loop", you just make that variable very local and give it a meaningless name, this is the point of those idiomatic i-j-k variables in for-loops).

The reason why you often see people declaring all variables at the start of the function is due to an old C standard (C89 and earlier) that required all variables to be declared at the start of a scope (note that that includes at the start of inner scopes, i.e. any { } block). But, that is not even standard C anymore (although some platforms are limited to the old standards ANSI C89). And if some of your professors or book authors seem to be using this style, it is probably because they are old and very resilient to change. Many people have successfully made the argument that more local and scope-limited declarations of variables is preferable for many reasons (like the few that I mentioned), and thus, it is considered better practice to do so (and the C99 standard also confirms that even hard-core C programmers agree that it is better practice).

commented: Indeed. +1

That's funny ravenous, because neither of your two codes compiled for me.

commented: of course it doesn't! +0

That's funny ravenous, because neither of your two codes compiled for me.

Of course not! They're not complete programs. You can probably get a bit further by putting the headers in etc.

Of course not! They're not complete programs. You can probably get a bit further by putting the headers in etc.

No, no, I meant even with the headers they still don't work. :(

No, no, I meant even with the headers they still don't work. :(

I guess there could be some minor errors. I didn't try to compile them, I just typed them directly into Daniweb. I hope you get the general idea though.

I guess there could be some minor errors. I didn't try to compile them, I just typed them directly into Daniweb. I hope you get the general idea though.

Actually, I don't. :(

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.