3

I have a list of global variables like this:

int a, b, c, d;

These variables are used in functions designed to count them, like:

int my_func(string x)
{
 //count var a//
}

Now I would like to use 'a' and e.g. 'b' as an arguments for another function which I declare this way:

int multiplication(int a, int b);

and define this way:

int multiplication(int a, int b)
{
c = a * b;
return c;
}

When I run it, I get the below error:

 ac.c:75:27: error: declaration shadows a variable in the global scope [-Werror,-Wshadow]
int multiplication(int a, int b)
                       ^
ac.c:7:41: note: previous declaration is here
int a, b, c, d;

How can I fix it? When I try to declare those variables inside functions, the whole program returns many errors.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
piotrektnw
  • 120
  • 7
  • 3
    Can you not simply use a different variable name? You can re-allow variable shadowing, but its generally much clearer not to use the same name for multiple variables. – Brian61354270 Jul 08 '20 at 12:25
  • 3
    Does this answer your question? [error in c: declaration shadows a variable in the global scope](https://stackoverflow.com/questions/53238366/error-in-c-declaration-shadows-a-variable-in-the-global-scope) – Brian61354270 Jul 08 '20 at 12:27
  • If they are global, why pass them as arguments...... but then, you should just not use globals, and you won't have the problem of duplicate/shadowing variable names at all. – underscore_d Jul 08 '20 at 13:14
  • 1
    Accessing global state in functions is considered a bad design choice, as it makes parts of your program [tightly coupled](https://en.wikipedia.org/wiki/Coupling_(computer_programming)). Mutating global variables is an even worse design choice. Whenever possible, try to make functions that pass all relevant data through parameters only. Mathematical functions like `multiplication` have absolutely no reason to access or mutate global state. – vgru Jul 08 '20 at 13:47
  • Note that your error isn't really an error: **it's your compiler being really helpful** (leave it as it is). If you really want to do it the way you have it (**bad idea**) just compile with different compiler options, specifically omit `-Werror` (which turns warnings into errors). – pmg Jul 08 '20 at 14:29
  • Turn off `-Wshadow` (`-Wno-shadow`) or use different names so that there's no shadowing. Simple as that. Shadowing is a feature of C. `-Wshadow` is a voluntary, nonstandard way to choose to be warned about it (or to abort compilation when it's combined with `-Werror`). If you don't want it, don't compile with it. – Petr Skocik Jul 08 '20 at 14:51

1 Answers1

3

You cannot use global variables as parameters of a function. That would make no sense either.

int multiplication (int a, int b) 

What happens here in truth is that a and b are two separate function-local variables inside of the function multiplication.

They are not references for the global variables with the same names.

As function-local variables have higher priority, they shadow the global variables at the scope of the function, which means that if you use/address a or b inside of the function, they refer to the local variables, not the global ones.

That's what the diagnostic of:

"declaration shadows a variable in the global scope"

says to you. The declaration of the local variables shadows the global variable declarations inside of the function multiplication.


What you can do is pass the global variables as arguments by value to the function multiplication:

#include <stdio.h>

int multiplication (int a, int b);

int a = 5, b = 10, c = 15, d = 20; 

int main (void)
{
    printf("Product: %d", multiplication(a,b));   // arguments, global variables.
}

int multiplication (int a, int b)                 // parameters, local variables.
{                                 
    return a * b;
}

Output:

Product: 50

In this way shadowing still occurs but it isn't problematic, if you add the specific -Wno-shadow flag to turn off warnings/errors for shadowing. This is usually only a warning to hint you that shadowing occurs. Shadowing itself is not harmful.

That it is treated as error is caused by the -Werror flag, which displays warnings as erros. -Werror is great, but you should be able to differentiate real errors (issues that won't get the code compiled anyway) and only warnings which are just shown as errors to prevent code being executed with any reasonable things which potentially can give you issues with regard to the successful implementation of the algorithm or the execution.

Or just rename the parameters to a different name to make the compiler not show these warnings.


If you only want to use global variables inside of the function multiplication, you could just use c = a * b; inside of main() and omit the whole function multiplication then:

#include <stdio.h>

int a = 5, b = 10, c = 15, d = 20; 

int main (void)
{
    c = a * b;
    printf("Product: %d", c);
}

Output:

Product: 50

To use a function which changes only global variables is considered as bad practice.


Side notes:

  • You should avoid global variables whenever possible, where you could pass values either by value or by reference as arguments instead.

    If you got a lot of functions, where you need to pass the value of the same variable into it would make sense to use global variables.

  • Also as you seem to confuse the terms "argument" and "parameter", take a look at here:

    What's the difference between an argument and a parameter?