Should arguments always be passed to functions or can variables outside of the scope of the function be used in the function?

I have a function that will only be used in the software I am making. It's in the .cpp file containig main().

Is it okay in this case to not pass arguments to that function but use global variables, and setters and getters from other classes directly in that function or should I always be looking to use parameters scoped to the function?

And how about using reference variables for function parameters, so that values of variables outside of the scope of a function can be modified from within the function? Is that acceptable or is it even more discouraged?
Last edited on
There's nothing stopping you from using global variables. However, the changes to these globals by the function are collectively called side effects, and that's not a good thing.

You might not notice the effects in your program when you write it, but if your functionality needs to be pulled out into a library (so it can be used more widely), you'll have major problems.

Many of the changes to C++ are to reduce the scope of things, so they're not globally visible/accessible.
Yeah the function will never be used anywhere else but at the same time I want to code properly lol. Choices, choices. I think I'll refactor. I prefer my default coding style to adhere to conventions as much as possible although it would be faster to take shortcuts.
If you end up not using arguments to your function (and you SHOULD use arguments to your function), don't use global variables. Instead use (file level) static variables.

Declare the variable the same way you would declare a global, but use the keyword static . The variable will then be available within the file, so your function can use it. But the variable will not be available outside of the file where name collisions could occur, or rogue code could accidentally change it.

But, passing arguments is still a better approach.
How many arguments are we talking about? If it's many, there's way of reducing these (struct etc). Are they all input or input/output? If any are pure output then these should be returned from the function.
You could structure your program to be object-oriented. If those functions are member functions of some class then they may use all the member variables of a particular class object without passing parameters.

It really depends ... what you want to do.
And how about using reference variables for function parameters, so that values of variables outside of the scope of a function can be modified from within the function? Is that acceptable or is it even more discouraged?
> how about using reference variables for function parameters,
> so that values of variables outside of the scope of a function can be modified from within the function?

CoreGuidelines:

For “in-out” parameters, pass by reference to non-const
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-inout

For “out” output values, prefer return values to output parameters
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-out
@JLBorges: thanks. Good to know. That's what I do already.
OOP has several ways to make a global that isn't.
eg a static class member variable can be accessed anywhere via classname::variable and is effectively global, but its not at the global scope.
there are other similar tricks you can play with similar ideas.
The problem with these 'tricks' is that they obey the 'rule' that you don't use a global but introduce most (not all, but most) of the same problems if you don't add more to it than that (eg, reference counting like a pointer?). Will it work? yes, globals or global-likes work fine until you make a mistake. All but one or two of the global variable gotchas is simply that they make it easier to screw up your code without warning, and if you pay attention and the problem is small, it works. Still a bad idea, but ok, ppl gonna do what they do.
> a static class member variable can be accessed anywhere via classname::variable and is effectively global,

Only if it is declared as public (ie. there is no invariant associated with it).

Global variables (variables at namespace scope) are fine if there is no invariant associated with them
or if they are declared as const.
doug4 wrote:
Declare the variable the same way you would declare a global, but use the keyword static . The variable will then be available within the file, so your function can use it. But the variable will not be available outside of the file where name collisions could occur, or rogue code could accidentally change it.

Wouldn't the more modern, C++ way of doing this be to use an anonymous namespace?
Yes, anonymous namespaces have one extra features in that you can put a class definition within the namespace. But mostly it's just an alternative; some people like that the static keyword is immediately visible, while a long namespace block might not be.
Wouldn't the more modern, C++ way of doing this be to use an anonymous namespace?


Could be. I haven't had the opportunity to use an anonymous namespace, so I really can't comment on it.

The emphasis of my post was, if arguments are going to be eschewed, make the scope as restrictive as possible. When the functions are in the same file, then file level scoping is better than global scope.

If anonymous namespaces gives you that (and I suppose they do), then they are also a better option than global variables. And at least as good an option, if not better, than file-static variables.
If the global/file level variables are only used by 1 function, then these could be static variables local to that function.

If they are used by a few functions, then perhaps put these and the functions that use them into a class.
> But mostly it's just an alternative; some people like that the static keyword is immediately visible

Both have internal linkage; but there is one difference: names declared in an unnamed namespace can be found only by qualified/unqualified name look up; they are not found by ADL.


> If they are used by a few functions, then perhaps put these and the functions that use them into a class.

That (a singleton class where everything is static) is the Java way; and admittedly there is a lot of Java-style C++ code. I strongly favour the style used by the standard library: group them by placing them in a namespace eg. std::this_thread (All names declared within an unnamed namespace have internal linkage)
Last edited on
Topic archived. No new replies allowed.