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?
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.
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?
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.
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.
> 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)